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 endCodeLine();
312
313 *m_t << "\\end{" << style << "}\n";
314}
315
316
317//-------------------------------
318
325
338
340{
341 if (this!=&og)
342 {
343 m_dir = og.m_dir;
344 m_codeList = std::make_unique<OutputCodeList>(*og.m_codeList);
346 m_codeGen->setTextStream(&m_t);
349 m_relPath = og.m_relPath;
350 m_indent = og.m_indent;
353 }
354 return *this;
355}
356
358
363
365{
366 bool generateBib = !CitationManager::instance().isEmpty();
367 QCString fileName=Config_getString(LATEX_OUTPUT)+"/Makefile";
368 std::ofstream f = Portable::openOutputStream(fileName);
369 if (!f.is_open())
370 {
371 term("Could not open file {} for writing\n",fileName);
372 }
373 TextStream t(&f);
374 // inserted by KONNO Akihisa <konno@researchers.jp> 2002-03-05
375 QCString latex_command = theTranslator->latexCommandName().quoted();
376 QCString mkidx_command = Config_getString(MAKEINDEX_CMD_NAME).quoted();
377 QCString bibtex_command = "bibtex";
378 QCString manual_file = "refman";
379 const int latex_count = 8;
380 // end insertion by KONNO Akihisa <konno@researchers.jp> 2002-03-05
381 t << "LATEX_CMD?=" << latex_command << "\n"
382 << "MKIDX_CMD?=" << mkidx_command << "\n"
383 << "BIBTEX_CMD?=" << bibtex_command << "\n"
384 << "LATEX_COUNT?=" << latex_count << "\n"
385 << "MANUAL_FILE?=" << manual_file << "\n"
386 << "\n";
387 if (!Config_getBool(USE_PDFLATEX)) // use plain old latex
388 {
389 t << "all: $(MANUAL_FILE).dvi\n"
390 << "\n"
391 << "ps: $(MANUAL_FILE).ps\n"
392 << "\n"
393 << "pdf: $(MANUAL_FILE).pdf\n"
394 << "\n"
395 << "ps_2on1: $(MANUAL_FILE).ps\n"
396 << "\n"
397 << "pdf_2on1: $(MANUAL_FILE).pdf\n"
398 << "\n"
399 << "$(MANUAL_FILE).ps: $(MANUAL_FILE).dvi\n"
400 << "\tdvips -o $(MANUAL_FILE).ps $(MANUAL_FILE).dvi\n"
401 << "\n";
402 t << "$(MANUAL_FILE).pdf: $(MANUAL_FILE).ps\n";
403 t << "\tps2pdf $(MANUAL_FILE).ps $(MANUAL_FILE).pdf\n\n";
404 t << "$(MANUAL_FILE).dvi: clean $(MANUAL_FILE).tex doxygen.sty\n"
405 << "\techo \"Running latex...\"\n"
406 << "\t$(LATEX_CMD) $(MANUAL_FILE).tex || \\\n"
407 << "\tif [ $$? != 0 ] ; then \\\n"
408 << "\t \\echo \"Please consult $(MANUAL_FILE).log to see the error messages\" ; \\\n"
409 << "\t false; \\\n"
410 << "\tfi\n"
411 << "\techo \"Running makeindex...\"\n"
412 << "\t$(MKIDX_CMD) $(MANUAL_FILE).idx\n";
413 if (generateBib)
414 {
415 t << "\techo \"Running bibtex...\"\n";
416 t << "\t$(BIBTEX_CMD) $(MANUAL_FILE)\n";
417 t << "\techo \"Rerunning latex....\"\n";
418 t << "\t$(LATEX_CMD) $(MANUAL_FILE).tex || \\\n"
419 << "\tif [ $$? != 0 ] ; then \\\n"
420 << "\t \\echo \"Please consult $(MANUAL_FILE).log to see the error messages\" ; \\\n"
421 << "\t false; \\\n"
422 << "\tfi\n";
423 }
424 t << "\techo \"Rerunning latex....\"\n"
425 << "\t$(LATEX_CMD) $(MANUAL_FILE).tex\n"
426 << "\tlatex_count=$(LATEX_COUNT) ; \\\n"
427 << "\twhile grep -E -s 'Rerun (LaTeX|to get cross-references right|to get bibliographical references right)' $(MANUAL_FILE).log && [ $$latex_count -gt 0 ] ;\\\n"
428 << "\t do \\\n"
429 << "\t echo \"Rerunning latex....\" ;\\\n"
430 << "\t $(LATEX_CMD) $(MANUAL_FILE).tex ; \\\n"
431 << "\t $(LATEX_CMD) $(MANUAL_FILE).tex || \\\n"
432 << "\t if [ $$? != 0 ] ; then \\\n"
433 << "\t \\echo \"Please consult $(MANUAL_FILE).log to see the error messages\" ; \\\n"
434 << "\t false; \\\n"
435 << "\t fi; \\\n"
436 << "\t latex_count=`expr $$latex_count - 1` ;\\\n"
437 << "\t done\n"
438 << "\t$(MKIDX_CMD) $(MANUAL_FILE).idx\n"
439 << "\t$(LATEX_CMD) $(MANUAL_FILE).tex || \\\n"
440 << "\tif [ $$? != 0 ] ; then \\\n"
441 << "\t \\echo \"Please consult $(MANUAL_FILE).log to see the error messages\" ; \\\n"
442 << "\t false; \\\n"
443 << "\tfi\n"
444 << "$(MANUAL_FILE).ps: $(MANUAL_FILE).ps\n"
445 << "\tpsnup -2 $(MANUAL_FILE).ps >$(MANUAL_FILE).ps\n"
446 << "\n"
447 << "$(MANUAL_FILE).pdf: $(MANUAL_FILE).ps\n"
448 << "\tps2pdf $(MANUAL_FILE).ps $(MANUAL_FILE).pdf\n";
449 }
450 else // use pdflatex for higher quality output
451 {
452 t << "all: $(MANUAL_FILE).pdf\n\n"
453 << "pdf: $(MANUAL_FILE).pdf\n\n";
454 t << "$(MANUAL_FILE).pdf: clean $(MANUAL_FILE).tex\n";
455 t << "\t$(LATEX_CMD) $(MANUAL_FILE) || \\\n"
456 << "\tif [ $$? != 0 ] ; then \\\n"
457 << "\t \\echo \"Please consult $(MANUAL_FILE).log to see the error messages\" ; \\\n"
458 << "\t false; \\\n"
459 << "\tfi\n";
460 t << "\t$(MKIDX_CMD) $(MANUAL_FILE).idx\n";
461 if (generateBib)
462 {
463 t << "\t$(BIBTEX_CMD) $(MANUAL_FILE)\n";
464 t << "\t$(LATEX_CMD) $(MANUAL_FILE) || \\\n"
465 << "\tif [ $$? != 0 ] ; then \\\n"
466 << "\t \\echo \"Please consult $(MANUAL_FILE).log to see the error messages\" ; \\\n"
467 << "\t false; \\\n"
468 << "\tfi\n";
469 }
470 t << "\t$(LATEX_CMD) $(MANUAL_FILE) || \\\n"
471 << "\tif [ $$? != 0 ] ; then \\\n"
472 << "\t \\echo \"Please consult $(MANUAL_FILE).log to see the error messages\" ; \\\n"
473 << "\t false; \\\n"
474 << "\tfi\n"
475 << "\tlatex_count=$(LATEX_COUNT) ; \\\n"
476 << "\twhile grep -E -s 'Rerun (LaTeX|to get cross-references right|to get bibliographical references right)' $(MANUAL_FILE).log && [ $$latex_count -gt 0 ] ;\\\n"
477 << "\t do \\\n"
478 << "\t echo \"Rerunning latex....\" ;\\\n"
479 << "\t $(LATEX_CMD) $(MANUAL_FILE) || \\\n"
480 << "\t if [ $$? != 0 ] ; then \\\n"
481 << "\t \\echo \"Please consult $(MANUAL_FILE).log to see the error messages\" ; \\\n"
482 << "\t false; \\\n"
483 << "\t fi; \\\n"
484 << "\t latex_count=`expr $$latex_count - 1` ;\\\n"
485 << "\t done\n"
486 << "\t$(MKIDX_CMD) $(MANUAL_FILE).idx\n"
487 << "\t$(LATEX_CMD) $(MANUAL_FILE) || \\\n"
488 << "\tif [ $$? != 0 ] ; then \\\n"
489 << "\t \\echo \"Please consult $(MANUAL_FILE).log to see the error messages\" ; \\\n"
490 << "\t false; \\\n"
491 << "\tfi\n";
492 }
493
494 t << "\n"
495 << "clean:\n"
496 << "\trm -f "
497 << "*.ps *.dvi *.aux *.toc *.idx *.ind *.ilg *.log *.out *.brf *.blg *.bbl $(MANUAL_FILE).pdf\n";
498}
499
500static void writeMakeBat()
501{
502#if defined(_MSC_VER)
503 QCString dir=Config_getString(LATEX_OUTPUT);
504 QCString fileName=dir+"/make.bat";
505 QCString latex_command = theTranslator->latexCommandName().quoted();
506 QCString mkidx_command = Config_getString(MAKEINDEX_CMD_NAME).quoted();
507 QCString bibtex_command = "bibtex";
508 QCString manual_file = "refman";
509 const int latex_count = 8;
510 bool generateBib = !CitationManager::instance().isEmpty();
511 std::ofstream t = Portable::openOutputStream(fileName);
512 if (!t.is_open())
513 {
514 term("Could not open file {} for writing\n",fileName);
515 }
516 t << "pushd %~dp0\r\n";
517 t << "if not %errorlevel% == 0 goto :end1\r\n";
518 t << "\r\n";
519 t << "set ORG_LATEX_CMD=%LATEX_CMD%\r\n";
520 t << "set ORG_MKIDX_CMD=%MKIDX_CMD%\r\n";
521 t << "set ORG_BIBTEX_CMD=%BIBTEX_CMD%\r\n";
522 t << "set ORG_LATEX_COUNT=%LATEX_COUNT%\r\n";
523 t << "set ORG_MANUAL_FILE=%MANUAL_FILE%\r\n";
524 t << "if \"X\"%LATEX_CMD% == \"X\" set LATEX_CMD=" << latex_command << "\r\n";
525 t << "if \"X\"%MKIDX_CMD% == \"X\" set MKIDX_CMD=" << mkidx_command << "\r\n";
526 t << "if \"X\"%BIBTEX_CMD% == \"X\" set BIBTEX_CMD=" << bibtex_command << "\r\n";
527 t << "if \"X\"%LATEX_COUNT% == \"X\" set LATEX_COUNT=" << latex_count << "\r\n";
528 t << "if \"X\"%MANUAL_FILE% == \"X\" set MANUAL_FILE=" << manual_file << "\r\n";
529 t << "\r\n";
530 t << "del /s /f *.ps *.dvi *.aux *.toc *.idx *.ind *.ilg *.log *.out *.brf *.blg *.bbl %MANUAL_FILE%.pdf\r\n\r\n";
531 t << "\r\n";
532 if (!Config_getBool(USE_PDFLATEX)) // use plain old latex
533 {
534 t << "%LATEX_CMD% %MANUAL_FILE%.tex\r\n";
535 t << "@if ERRORLEVEL 1 goto :error\r\n";
536 t << "echo ----\r\n";
537 t << "%MKIDX_CMD% %MANUAL_FILE%.idx\r\n";
538 if (generateBib)
539 {
540 t << "%BIBTEX_CMD% %MANUAL_FILE%\r\n";
541 t << "echo ----\r\n";
542 t << "\t%LATEX_CMD% %MANUAL_FILE%.tex\r\n";
543 t << "@if ERRORLEVEL 1 goto :error\r\n";
544 }
545 t << "setlocal enabledelayedexpansion\r\n";
546 t << "set count=%LAT#EX_COUNT%\r\n";
547 t << ":repeat\r\n";
548 t << "set content=X\r\n";
549 t << "for /F \"tokens=*\" %%T in ( 'findstr /C:\"Rerun LaTeX\" %MANUAL_FILE%.log' ) do set content=\"%%~T\"\r\n";
550 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";
551 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";
552 t << "if !content! == X goto :skip\r\n";
553 t << "set /a count-=1\r\n";
554 t << "if !count! EQU 0 goto :skip\r\n\r\n";
555 t << "echo ----\r\n";
556 t << "%LATEX_CMD% %MANUAL_FILE%.tex\r\n";
557 t << "@if ERRORLEVEL 1 goto :error\r\n";
558 t << "goto :repeat\r\n";
559 t << ":skip\r\n";
560 t << "endlocal\r\n";
561 t << "%MKIDX_CMD% %MANUAL_FILE%.idx\r\n";
562 t << "%LATEX_CMD% %MANUAL_FILE%.tex\r\n";
563 t << "@if ERRORLEVEL 1 goto :error\r\n";
564 t << "dvips -o %MANUAL_FILE%.ps %MANUAL_FILE%.dvi\r\n";
566 t << " -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite "
567 "-sOutputFile=%MANUAL_FILE%.pdf -c save pop -f %MANUAL_FILE%.ps\r\n";
568 }
569 else // use pdflatex
570 {
571 t << "%LATEX_CMD% %MANUAL_FILE%\r\n";
572 t << "@if ERRORLEVEL 1 goto :error\r\n";
573 t << "echo ----\r\n";
574 t << "%MKIDX_CMD% %MANUAL_FILE%.idx\r\n";
575 if (generateBib)
576 {
577 t << "%BIBTEX_CMD% %MANUAL_FILE%\r\n";
578 t << "%LATEX_CMD% %MANUAL_FILE%\r\n";
579 t << "@if ERRORLEVEL 1 goto :error\r\n";
580 }
581 t << "echo ----\r\n";
582 t << "%LATEX_CMD% %MANUAL_FILE%\r\n";
583 t << "@if ERRORLEVEL 1 goto :error\r\n";
584 t << "\r\n";
585 t << "setlocal enabledelayedexpansion\r\n";
586 t << "set count=%LATEX_COUNT%\r\n";
587 t << ":repeat\r\n";
588 t << "set content=X\r\n";
589 t << "for /F \"tokens=*\" %%T in ( 'findstr /C:\"Rerun LaTeX\" %MANUAL_FILE%.log' ) do set content=\"%%~T\"\r\n";
590 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";
591 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";
592 t << "if !content! == X goto :skip\r\n";
593 t << "set /a count-=1\r\n";
594 t << "if !count! EQU 0 goto :skip\r\n\r\n";
595 t << "echo ----\r\n";
596 t << "%LATEX_CMD% %MANUAL_FILE%\r\n";
597 t << "@if ERRORLEVEL 1 goto :error\r\n";
598 t << "goto :repeat\r\n";
599 t << ":skip\r\n";
600 t << "endlocal\r\n";
601 t << "%MKIDX_CMD% %MANUAL_FILE%.idx\r\n";
602 t << "%LATEX_CMD% %MANUAL_FILE%\r\n";
603 t << "@if ERRORLEVEL 1 goto :error\r\n";
604 }
605 t<< "\r\n";
606 t << "goto :end\r\n";
607 t << ":error\r\n";
608 t << "@echo ===============\r\n";
609 t << "@echo Please consult %MANUAL_FILE%.log to see the error messages\r\n";
610 t << "@echo ===============\r\n";
611 t<< "\r\n";
612 t<< ":end\r\n";
613 t<< "@REM reset environment\r\n";
614 t<< "popd\r\n";
615 t<< "set LATEX_CMD=%ORG_LATEX_CMD%\r\n";
616 t<< "set ORG_LATEX_CMD=\r\n";
617 t<< "set MKIDX_CMD=%ORG_MKIDX_CMD%\r\n";
618 t<< "set ORG_MKIDX_CMD=\r\n";
619 t<< "set BIBTEX_CMD=%ORG_BIBTEX_CMD%\r\n";
620 t<< "set ORG_BIBTEX_CMD=\r\n";
621 t<< "set MANUAL_FILE=%ORG_MANUAL_FILE%\r\n";
622 t<< "set ORG_MANUAL_FILE=\r\n";
623 t<< "set LATEX_COUNT=%ORG_LATEX_COUNT%\r\n";
624 t<< "set ORG_LATEX_COUNT=\r\n";
625 t<< "\r\n";
626 t<< ":end1\r\n";
627#endif
628}
629
631{
632 QCString dname = Config_getString(LATEX_OUTPUT);
633 Dir d(dname.str());
634 if (!d.exists() && !d.mkdir(dname.str()))
635 {
636 term("Could not create output directory {}\n",dname);
637 }
638
639 if (!Config_getString(LATEX_HEADER).isEmpty())
640 {
641 g_header_file=Config_getString(LATEX_HEADER);
643 //printf("g_header='%s'\n",qPrint(g_header));
646 }
647 else
648 {
649 g_header_file = "header.tex";
652 checkBlocks(result,"<default header.tex>",latexMarkerInfo);
653 }
654 if (!Config_getString(LATEX_FOOTER).isEmpty())
655 {
656 g_footer_file=Config_getString(LATEX_FOOTER);
658 //printf("g_footer='%s'\n",qPrint(g_footer));
661 }
662 else
663 {
664 g_footer_file = "footer.tex";
667 checkBlocks(result,"<default footer.tex>",latexMarkerInfo);
668 }
669
671 writeMakeBat();
672
673 createSubDirs(d);
674}
675
677{
678 QCString dname = Config_getString(LATEX_OUTPUT);
679 Dir d(dname.str());
680 clearSubDirs(d);
681}
682
684{
685 t << ResourceMgr::instance().getAsString("doxygen.sty");
686}
687
689{
690 t << "% Latex header for doxygen " << getDoxygenVersion() << "\n";
691 t << ResourceMgr::instance().getAsString("header.tex");
692}
693
695{
696 t << "% Latex footer for doxygen " << getDoxygenVersion() << "\n";
697 t << ResourceMgr::instance().getAsString("footer.tex");
698}
699
701{
702 t << "% stylesheet for doxygen " << getDoxygenVersion() << "\n";
704}
705
706void LatexGenerator::startFile(const QCString &name,const QCString &,const QCString &,int,int hierarchyLevel)
707{
708#if 0
709 setEncoding(Config_getString(LATEX_OUTPUT_ENCODING));
710#endif
711 QCString fileName=name;
712 m_hierarchyLevel = hierarchyLevel;
714 if (!fileName.endsWith(".tex") && !fileName.endsWith(".sty")) fileName+=".tex";
716 m_codeGen->setRelativePath(m_relPath);
717 m_codeGen->setSourceFileName(stripPath(fileName));
718}
719
721{
722 endPlainFile();
723 m_codeGen->setSourceFileName("");
724}
725
726//void LatexGenerator::writeIndex()
727//{
728// startFile("refman.tex");
729//}
730
732{
733 m_t << "\\\\[1ex]\\large ";
734}
735
737{
738 QCString result;
739 const StringVector &extraLatexStyles = Config_getList(LATEX_EXTRA_STYLESHEET);
740 for (const auto &fileName : extraLatexStyles)
741 {
742 if (!fileName.empty())
743 {
744 FileInfo fi(fileName);
745 if (fi.exists())
746 {
747 result += "\\usepackage{";
749 {
750 // strip the extension, it will be added by the usepackage in the tex conversion process
752 }
753 else
754 {
755 result += fi.fileName();
756 }
757 result += "}\n";
758 }
759 }
760 }
761 return result;
762}
763
765{
766 QCString result;
767 QCString latex_mkidx_command = Config_getString(LATEX_MAKEINDEX_CMD);
768 if (!latex_mkidx_command.isEmpty())
769 {
770 if (latex_mkidx_command[0] == '\\')
771 result += latex_mkidx_command;
772 else
773 result += "\\"+latex_mkidx_command;
774 }
775 else
776 {
777 result += "\\makeindex";
778 }
779 return result;
780}
781
783{
784 switch (Config_getEnum(LATEX_BATCHMODE))
785 {
786 case LATEX_BATCHMODE_t::NO: return "";
787 case LATEX_BATCHMODE_t::YES: return "\\batchmode";
788 case LATEX_BATCHMODE_t::BATCH: return "\\batchmode";
789 case LATEX_BATCHMODE_t::NON_STOP: return "\\nonstopmode";
790 case LATEX_BATCHMODE_t::SCROLL: return "\\scrollmode";
791 case LATEX_BATCHMODE_t::ERROR_STOP: return "\\errorstopmode";
792 }
793 return "";
794}
795
797 const QCString &str,
798 const QCString &title)
799{
800 bool compactLatex = Config_getBool(COMPACT_LATEX);
801 bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
802 bool usePdfLatex = Config_getBool(USE_PDFLATEX);
803 QCString paperType = Config_getEnumAsString(PAPER_TYPE);
804
805 QCString style = Config_getString(LATEX_BIB_STYLE);
806 if (style.isEmpty())
807 {
808 style="plainnat";
809 }
810
811 TextStream tg;
812 QCString generatedBy;
813 auto timeStamp = Config_getEnum(TIMESTAMP);
814 switch (timeStamp)
815 {
816 case TIMESTAMP_t::YES:
817 case TIMESTAMP_t::DATETIME:
818 generatedBy = theTranslator->trGeneratedAt(dateToString(DateTimeType::DateTime),
819 Config_getString(PROJECT_NAME));
820 break;
821 case TIMESTAMP_t::DATE:
822 generatedBy = theTranslator->trGeneratedAt(dateToString(DateTimeType::Date),
823 Config_getString(PROJECT_NAME));
824 break;
825 case TIMESTAMP_t::NO:
826 generatedBy = theTranslator->trGeneratedBy();
827 break;
828 }
829 filterLatexString(tg, generatedBy,
830 false, // insideTabbing
831 false, // insidePre
832 false, // insideItem
833 false, // insideTable
834 false // keepSpaces
835 );
836 generatedBy = tg.str();
837
838 QCString latexFontenc = theTranslator->latexFontenc();
839
840 QCString latexEmojiDirectory = Config_getString(LATEX_EMOJI_DIRECTORY);
841 if (latexEmojiDirectory.isEmpty()) latexEmojiDirectory = ".";
842 latexEmojiDirectory = substitute(latexEmojiDirectory,"\\","/");
843
844 TextStream tg1;
846 QCString extraLatexPackages = tg1.str();
847
848 TextStream tg2;
850 QCString latexSpecialFormulaChars = tg2.str();
851
852 QCString formulaMacrofile = Config_getString(FORMULA_MACROFILE);
853 QCString stripMacroFile;
854 if (!formulaMacrofile.isEmpty())
855 {
856 FileInfo fi(formulaMacrofile.str());
857 formulaMacrofile=fi.absFilePath();
858 stripMacroFile = fi.fileName();
859 copyFile(formulaMacrofile,Config_getString(LATEX_OUTPUT) + "/" + stripMacroFile);
860 }
861
862 QCString projectNumber = Config_getString(PROJECT_NUMBER);
863
864 // first substitute generic keywords
865 QCString result = substituteKeywords(file,str,title,
866 convertToLaTeX(Config_getString(PROJECT_NAME),false),
867 convertToLaTeX(projectNumber,false),
868 convertToLaTeX(Config_getString(PROJECT_BRIEF),false));
869
870 // additional LaTeX only keywords
871 result = substituteKeywords(file,result,
872 {
873 // keyword value getter
874 { "$latexdocumentpre", [&]() { return theTranslator->latexDocumentPre(); } },
875 { "$latexdocumentpost", [&]() { return theTranslator->latexDocumentPost(); } },
876 { "$generatedby", [&]() { return generatedBy; } },
877 { "$latexbibstyle", [&]() { return style; } },
878 { "$latexcitereference", [&]() { return theTranslator->trCiteReferences(); } },
879 { "$latexbibfiles", [&]() { return CitationManager::instance().latexBibFiles(); } },
880 { "$papertype", [&]() { return paperType+"paper"; } },
881 { "$extralatexstylesheet", [&]() { return extraLatexStyleSheet(); } },
882 { "$languagesupport", [&]() { return theTranslator->latexLanguageSupportCommand(); } },
883 { "$latexfontenc", [&]() { return latexFontenc; } },
884 { "$latexfont", [&]() { return theTranslator->latexFont(); } },
885 { "$latexemojidirectory", [&]() { return latexEmojiDirectory; } },
886 { "$makeindex", [&]() { return makeIndex(); } },
887 { "$extralatexpackages", [&]() { return extraLatexPackages; } },
888 { "$latexspecialformulachars", [&]() { return latexSpecialFormulaChars; } },
889 { "$formulamacrofile", [&]() { return stripMacroFile; } },
890 { "$latex_batchmode", [&]() { return latex_batchmode(); } }
891 });
892
893 // remove conditional blocks
894 result = selectBlocks(result,
895 {
896 // marker is enabled
897 { "CITATIONS_PRESENT", !CitationManager::instance().isEmpty() },
898 { "COMPACT_LATEX", compactLatex },
899 { "PDF_HYPERLINKS", pdfHyperlinks },
900 { "USE_PDFLATEX", usePdfLatex },
901 { "TIMESTAMP", timeStamp!=TIMESTAMP_t::NO },
902 { "LATEX_FONTENC", !latexFontenc.isEmpty() },
903 { "FORMULA_MACROFILE", !formulaMacrofile.isEmpty() },
904 { "PROJECT_NUMBER", !projectNumber.isEmpty() }
906
907 result = removeEmptyLines(result);
908
909 return result;
910}
911
913{
914 bool compactLatex = Config_getBool(COMPACT_LATEX);
915 switch (is)
916 {
919 break;
921 break;
923 break;
925 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
926 m_t << "{"; //Module Index}\n"
927 break;
929 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
930 m_t << "{"; //Topic Index}\n"
931 break;
933 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
934 m_t << "{"; //Directory Index}\n"
935 break;
937 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
938 m_t << "{"; //Namespace Index}\n"
939 break;
941 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
942 m_t << "{"; //Concept Index}\n"
943 break;
945 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
946 m_t << "{"; //Hierarchical Index}\n"
947 break;
949 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
950 m_t << "{"; //Annotated Compound Index}\n"
951 break;
953 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
954 m_t << "{"; //Annotated File Index}\n"
955 break;
957 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
958 m_t << "{"; //Annotated Page Index}\n"
959 break;
961 {
962 for (const auto &gd : *Doxygen::groupLinkedMap)
963 {
964 if (!gd->isReference())
965 {
966 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
967 m_t << "{"; //Topic Documentation}\n";
968 break;
969 }
970 }
971 }
972 break;
974 {
975 for (const auto &mod : ModuleManager::instance().modules())
976 {
977 if (!mod->isReference() && mod->isPrimaryInterface())
978 {
979 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
980 m_t << "{"; //Topic Documentation}\n";
981 break;
982 }
983 }
984 }
985 break;
987 {
988 for (const auto &dd : *Doxygen::dirLinkedMap)
989 {
990 if (dd->isLinkableInProject())
991 {
992 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
993 m_t << "{"; //Dir Documentation}\n";
994 break;
995 }
996 }
997 }
998 break;
1000 {
1001 for (const auto &nd : *Doxygen::namespaceLinkedMap)
1002 {
1003 if (nd->isLinkableInProject() && !nd->isAlias())
1004 {
1005 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
1006 m_t << "{"; // Namespace Documentation}\n":
1007 break;
1008 }
1009 }
1010 }
1011 break;
1013 {
1014 for (const auto &cd : *Doxygen::conceptLinkedMap)
1015 {
1016 if (cd->isLinkableInProject() && !cd->isAlias())
1017 {
1018 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
1019 m_t << "{"; // Concept Documentation}\n":
1020 break;
1021 }
1022 }
1023 }
1024 break;
1026 {
1027 for (const auto &cd : *Doxygen::classLinkedMap)
1028 {
1029 if (cd->isLinkableInProject() &&
1030 !cd->isImplicitTemplateInstance() &&
1031 !cd->isEmbeddedInOuterScope() &&
1032 !cd->isAlias()
1033 )
1034 {
1035 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
1036 m_t << "{"; //Compound Documentation}\n";
1037 break;
1038 }
1039 }
1040 }
1041 break;
1043 {
1044 bool isFirst=TRUE;
1045 for (const auto &fn : *Doxygen::inputNameLinkedMap)
1046 {
1047 for (const auto &fd : *fn)
1048 {
1049 if (fd->isLinkableInProject() || fd->generateSourceFile())
1050 {
1051 if (isFirst)
1052 {
1053 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
1054 m_t << "{"; //File Documentation}\n";
1055 isFirst=FALSE;
1056 break;
1057 }
1058 }
1059 }
1060 }
1061 }
1062 break;
1064 {
1065 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
1066 m_t << "{"; //Example Documentation}\n";
1067 }
1068 break;
1070 break;
1072 break;
1074 break;
1075 }
1076}
1077
1079{
1080 switch (is)
1081 {
1083 break;
1085 break;
1087 {
1089 {
1090 writePageLink(Doxygen::mainPage->getOutputFileBase(), FALSE);
1091 }
1092 }
1093 break;
1095 m_t << "}\n\\input{modules}\n";
1096 break;
1098 m_t << "}\n\\input{topics}\n";
1099 break;
1101 m_t << "}\n\\input{dirs}\n";
1102 break;
1104 m_t << "}\n\\input{namespaces}\n";
1105 break;
1107 m_t << "}\n\\input{concepts}\n";
1108 break;
1110 m_t << "}\n\\input{hierarchy}\n";
1111 break;
1113 m_t << "}\n\\input{annotated}\n";
1114 break;
1116 m_t << "}\n\\input{files}\n";
1117 break;
1119 m_t << "}\n\\input{pages}\n";
1120 break;
1122 {
1123 m_t << "}\n";
1124 for (const auto &gd : *Doxygen::groupLinkedMap)
1125 {
1126 if (!gd->isReference() && !gd->isASubGroup())
1127 {
1128 writePageLink(gd->getOutputFileBase(), FALSE);
1129 }
1130 }
1131 }
1132 break;
1134 {
1135 m_t << "}\n";
1136 for (const auto &mod : ModuleManager::instance().modules())
1137 {
1138 if (!mod->isReference() && mod->isPrimaryInterface())
1139 {
1140 writePageLink(mod->getOutputFileBase(), FALSE);
1141 }
1142 }
1143 }
1144 break;
1146 {
1147 bool found=FALSE;
1148 for (const auto &dd : *Doxygen::dirLinkedMap)
1149 {
1150 if (dd->isLinkableInProject())
1151 {
1152 if (!found)
1153 {
1154 m_t << "}\n";
1155 found = TRUE;
1156 }
1157 m_t << "\\input{" << dd->getOutputFileBase() << "}\n";
1158 }
1159 }
1160 }
1161 break;
1163 {
1164 bool found=FALSE;
1165 for (const auto &nd : *Doxygen::namespaceLinkedMap)
1166 {
1167 if (nd->isLinkableInProject() && !nd->isAlias())
1168 {
1169 if (!found)
1170 {
1171 m_t << "}\n";
1172 found=true;
1173 }
1174 m_t << "\\input{" << nd->getOutputFileBase() << "}\n";
1175 }
1176 }
1177 }
1178 break;
1180 {
1181 bool found=FALSE;
1182 for (const auto &cd : *Doxygen::conceptLinkedMap)
1183 {
1184 if (cd->isLinkableInProject() && !cd->isAlias())
1185 {
1186 if (!found)
1187 {
1188 m_t << "}\n";
1189 found=true;
1190 }
1191 m_t << "\\input{" << cd->getOutputFileBase() << "}\n";
1192 }
1193 }
1194 }
1195 break;
1197 {
1198 bool found=FALSE;
1199 for (const auto &cd : *Doxygen::classLinkedMap)
1200 {
1201 if (cd->isLinkableInProject() &&
1202 !cd->isImplicitTemplateInstance() &&
1203 !cd->isEmbeddedInOuterScope() &&
1204 !cd->isAlias()
1205 )
1206 {
1207 if (!found)
1208 {
1209 m_t << "}\n"; // end doxysection or chapter title
1210 found=TRUE;
1211 }
1212 m_t << "\\input{" << cd->getOutputFileBase() << "}\n";
1213 }
1214 }
1215 }
1216 break;
1218 {
1219 bool isFirst=TRUE;
1220 for (const auto &fn : *Doxygen::inputNameLinkedMap)
1221 {
1222 for (const auto &fd : *fn)
1223 {
1224 if (fd->isLinkableInProject())
1225 {
1226 if (isFirst)
1227 {
1228 m_t << "}\n"; // end doxysection or chapter title
1229 }
1230 isFirst=FALSE;
1231 m_t << "\\input{" << fd->getOutputFileBase() << "}\n";
1232 }
1233 if (fd->generateSourceFile())
1234 {
1235 if (isFirst)
1236 {
1237 m_t << "}\n"; // end doxysection or chapter title
1238 }
1239 isFirst=FALSE;
1240 m_t << "\\input{" << fd->getSourceFileBase() << "}\n";
1241 }
1242 }
1243 }
1244 }
1245 break;
1247 {
1248 m_t << "}\n";
1249 for (const auto &pd : *Doxygen::exampleLinkedMap)
1250 {
1251 m_t << "\\input{" << pd->getOutputFileBase() << "}\n";
1252 }
1253 }
1254 break;
1256 {
1257 for (const auto &pd : *Doxygen::pageLinkedMap)
1258 {
1259 if (!pd->getGroupDef() && !pd->isReference() && !pd->hasParentPage()
1260 && pd->name() != "citelist" && Doxygen::mainPage.get() != pd.get())
1261 {
1262 writePageLink(pd->getOutputFileBase(), FALSE);
1263 }
1264 }
1265 }
1266 break;
1268 break;
1271 break;
1272 }
1273}
1274
1275void LatexGenerator::writePageLink(const QCString &name, bool /*first*/)
1276{
1277 //bool &compactLatex = Config_getBool(COMPACT_LATEX);
1278 // next is remove for bug615957
1279 //if (compactLatex || first) m_t << "\\input" ; else m_t << "\\include";
1280 m_t << "\\input" ;
1281 m_t << "{" << name << "}\n";
1282}
1283
1285{
1286 if (part > 0)
1287 return;
1288
1289 startPlainFile("doxygen.sty");
1291 endPlainFile();
1292
1293 // workaround for the problem caused by change in LaTeX in version 2019
1294 // in the unmaintained tabu package
1295 startPlainFile("tabu_doxygen.sty");
1296 m_t << ResourceMgr::instance().getAsString("tabu_doxygen.sty");
1297 endPlainFile();
1298 startPlainFile("longtable_doxygen.sty");
1299 m_t << ResourceMgr::instance().getAsString("longtable_doxygen.sty");
1300 endPlainFile();
1301 /// an extension of the etoc package is required that is only available in the
1302 /// newer version. Providing the updated version to be used with older versions
1303 /// of LaTeX
1304 startPlainFile("etoc_doxygen.sty");
1305 m_t << ResourceMgr::instance().getAsString("etoc_doxygen.sty");
1306 endPlainFile();
1307}
1308
1310{
1311 m_t << "\n" << "\n";
1312}
1313
1315{
1316 m_t << "\n" << "\n";
1317}
1318
1320{
1321 m_t << text;
1322}
1323
1325{
1326 m_t << "\\item ";
1327 if (ref.isEmpty() && !fn.isEmpty())
1328 {
1329 m_t << "\\contentsline{section}{";
1330 }
1331}
1332
1334{
1335 if (ref.isEmpty() && !fn.isEmpty())
1336 {
1337 m_t << "}{\\pageref{" << stripPath(fn) << "}}{}\n";
1338 }
1339}
1340
1342 const QCString &path,const QCString &name)
1343{
1344 m_t << "\\item\\contentsline{section}\\textbf{ ";
1345 if (!path.isEmpty()) docify(path);
1346 docify(name);
1347 m_t << "} ";
1348}
1349
1351{
1352 m_t << "\\item\\contentsline{section}{";
1353}
1354
1358
1360{
1361 m_t << " ";
1362 if (hasBrief) m_t << "\\\\*";
1363}
1364
1365void LatexGenerator::endIndexValue(const QCString &name,bool /*hasBrief*/)
1366{
1367 //if (hasBrief) m_t << ")";
1368 m_t << "}{\\pageref{" << stripPath(name) << "}}{}\n";
1369}
1370
1371//void LatexGenerator::writeClassLink(const QCString &,const QCString &,
1372// const QCString &,const QCString &name)
1373//{
1374// m_t << "\\textbf{ ";
1375// docify(name);
1376// m_t << "}";
1377//}
1378
1380{
1381 bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
1382 if (!m_disableLinks && pdfHyperlinks)
1383 {
1384 m_t << "\\mbox{\\hyperlink{";
1385 if (!f.isEmpty()) m_t << stripPath(f);
1386 if (!anchor.isEmpty()) m_t << "_" << anchor;
1387 m_t << "}{";
1388 }
1389 else
1390 {
1391 m_t << "\\textbf{ ";
1392 }
1393}
1394
1396{
1397 bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
1398 if (!m_disableLinks && pdfHyperlinks)
1399 {
1400 m_t << "}";
1401 }
1402 m_t << "}";
1403}
1404
1405static QCString objectLinkToString(const QCString &ref, const QCString &f,
1406 const QCString &anchor, const QCString &text,
1407 bool insideTabbing,bool disableLinks)
1408{
1409 bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
1410 QCString result;
1411 if (!disableLinks && ref.isEmpty() && pdfHyperlinks)
1412 {
1413 result += "\\mbox{\\hyperlink{";
1414 if (!f.isEmpty()) result += stripPath(f);
1415 if (!f.isEmpty() && !anchor.isEmpty()) result += "_";
1416 if (!anchor.isEmpty()) result += anchor;
1417 result += "}{";
1418 result += convertToLaTeX(text,insideTabbing);
1419 result += "}}";
1420 }
1421 else
1422 {
1423 result += "\\textbf{ ";
1424 result += convertToLaTeX(text,insideTabbing);
1425 result += "}";
1426 }
1427 return result;
1428}
1429
1430static void processEntity(TextStream &t, bool pdfHyperlinks, const char *strForm, const char *strRepl)
1431{
1432 if (pdfHyperlinks)
1433 {
1434 t << "\\texorpdfstring{";
1435 }
1436 t << strForm;
1437 if (pdfHyperlinks)
1438 {
1439 t << "}{" << strRepl << "}";
1440 }
1441}
1442
1444 const QCString &anchor, const QCString &text)
1445{
1446 m_t << objectLinkToString(ref,f,anchor,text,m_codeGen->insideTabbing(),m_disableLinks);
1447}
1448
1450{
1451 m_t << " \\doxyref{}{";
1452}
1453
1454void LatexGenerator::endPageRef(const QCString &clname, const QCString &anchor)
1455{
1456 m_t << "}{";
1457 if (!clname.isEmpty()) m_t << clname;
1458 if (!anchor.isEmpty()) m_t << "_" << anchor;
1459 m_t << "}";
1460}
1461
1462
1464{
1465 int hierarchyLevel = m_hierarchyLevel;
1466 if (Config_getBool(COMPACT_LATEX))
1467 {
1468 ++hierarchyLevel;
1469 }
1470
1471 if (hierarchyLevel < 0)
1472 m_t << "\\chapter{";
1473 else
1474 m_t << "\\doxy" << QCString("sub").repeat(hierarchyLevel) << "section{";
1475}
1476
1478{
1479 m_t << "}\n";
1480
1481 bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
1482 bool usePDFLatex = Config_getBool(USE_PDFLATEX);
1483 if (usePDFLatex && pdfHyperlinks && !fileName.isEmpty())
1484 {
1485 m_t << "\\hypertarget{" << stripPath(fileName) << "}{}";
1486 }
1487
1489 if (!fn.isEmpty())
1490 {
1491 m_t << "\\label{" << fn << "}";
1492 }
1493 if (!name.isEmpty())
1494 {
1495 m_t << "\\index{";
1496 m_t << latexEscapeLabelName(name);
1497 m_t << "@{";
1498 m_t << latexEscapeIndexChars(name);
1499 m_t << "}}\n";
1500 }
1501}
1502
1504{
1505 if (Config_getBool(COMPACT_LATEX))
1506 {
1507 m_t << "\\doxysubsection{";
1508 }
1509 else
1510 {
1511 m_t << "\\doxysection{";
1512 }
1513}
1514
1515void LatexGenerator::startGroupHeader(int extraIndentLevel)
1516{
1517 if (Config_getBool(COMPACT_LATEX))
1518 {
1519 extraIndentLevel++;
1520 }
1521
1522 if (extraIndentLevel>=3)
1523 {
1524 m_t << "\\doxysubparagraph*{";
1525 }
1526 else if (extraIndentLevel==2)
1527 {
1528 m_t << "\\doxyparagraph{";
1529 }
1530 else
1531 {
1532 extraIndentLevel += m_hierarchyLevel + 1;
1533 m_t << "\\doxy" << QCString("sub").repeat(extraIndentLevel) << "section{";
1534 }
1536}
1537
1539{
1541 m_t << "}\n";
1542}
1543
1545{
1546 int l = m_hierarchyLevel + 1;
1547 if (Config_getBool(COMPACT_LATEX))
1548 {
1549 ++l;
1550 }
1551
1552 m_t << "\\doxysub" << QCString("sub").repeat(l) << "section*{";
1554}
1555
1557{
1559 m_t << "}\n";
1560}
1561
1563 const QCString &memname,
1564 const QCString &,
1565 const QCString &title,
1566 int memCount,
1567 int memTotal,
1568 bool showInline)
1569{
1570 if (!memname.isEmpty() && memname[0]!='@')
1571 {
1572 m_t << "\\index{";
1573 if (!clname.isEmpty())
1574 {
1575 m_t << latexEscapeLabelName(clname);
1576 m_t << "@{";
1577 m_t << latexEscapeIndexChars(clname);
1578 m_t << "}!";
1579 }
1580 m_t << latexEscapeLabelName(memname);
1581 m_t << "@{";
1582 m_t << latexEscapeIndexChars(memname);
1583 m_t << "}}\n";
1584
1585 m_t << "\\index{";
1586 m_t << latexEscapeLabelName(memname);
1587 m_t << "@{";
1588 m_t << latexEscapeIndexChars(memname);
1589 m_t << "}";
1590 if (!clname.isEmpty())
1591 {
1592 m_t << "!";
1593 m_t << latexEscapeLabelName(clname);
1594 m_t << "@{";
1595 m_t << latexEscapeIndexChars(clname);
1596 m_t << "}";
1597 }
1598 m_t << "}\n";
1599 }
1600 bool compactLatex = Config_getBool(COMPACT_LATEX);
1601 bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
1602 if (showInline)
1603 {
1604 m_t << "\\doxysubparagraph";
1605 }
1606 else if (compactLatex)
1607 {
1608 m_t << "\\doxyparagraph";
1609 }
1610 else
1611 {
1612 m_t << "\\doxy" << QCString("sub").repeat(m_hierarchyLevel + 2) << "section";
1613 }
1614
1615 m_t << "{";
1616 if (pdfHyperlinks)
1617 {
1618 m_t << "\\texorpdfstring{";
1619 }
1620 m_t << latexEscapeIndexChars(title);
1621 if (pdfHyperlinks)
1622 {
1623 m_t << "}{" << latexEscapePDFString(title) << "}";
1624 }
1625 if (memTotal>1)
1626 {
1627 m_t << "\\hspace{0.1cm}{\\footnotesize\\ttfamily [" << memCount << "/" << memTotal << "]}";
1628 }
1629 m_t << "}";
1630 m_t << "\n{\\footnotesize\\ttfamily ";
1631 //m_disableLinks=TRUE;
1632}
1633
1635{
1637 m_t << "}\n\n";
1638 //if (Config_getBool(COMPACT_LATEX)) m_t << "\\hfill";
1639}
1640
1642 const QCString &anchor, const QCString &,
1643 const QCString &)
1644{
1645 bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
1646 bool usePDFLatex = Config_getBool(USE_PDFLATEX);
1647 if (m_insideTableEnv) m_t << "\\mbox{"; // see issue #6093
1648 if (usePDFLatex && pdfHyperlinks)
1649 {
1650 m_t << "\\Hypertarget{";
1651 if (!fName.isEmpty()) m_t << stripPath(fName);
1652 if (!anchor.isEmpty()) m_t << "_" << anchor;
1653 m_t << "}";
1654 }
1655}
1656
1657void LatexGenerator::endDoxyAnchor(const QCString &/* fName */,const QCString &/* anchor */)
1658{
1659}
1660
1661void LatexGenerator::addLabel(const QCString &fName, const QCString &anchor)
1662{
1663 m_t << "\\label{";
1664 if (!fName.isEmpty()) m_t << stripPath(fName);
1665 if (!anchor.isEmpty()) m_t << "_" << anchor;
1666 if (m_insideTableEnv) m_t << "}";
1667 m_t << "} \n";
1668}
1669
1670void LatexGenerator::writeAnchor(const QCString &fName,const QCString &name)
1671{
1672 //printf("LatexGenerator::writeAnchor(%s,%s)\n",fName,name);
1673 m_t << "\\label{" << stripPath(name) << "}\n";
1674 bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
1675 bool usePDFLatex = Config_getBool(USE_PDFLATEX);
1676 if (usePDFLatex && pdfHyperlinks)
1677 {
1678 if (!fName.isEmpty())
1679 {
1680 m_t << "\\Hypertarget{" << stripPath(fName) << "_" << stripPath(name) << "}\n";
1681 }
1682 else
1683 {
1684 m_t << "\\Hypertarget{" << stripPath(name) << "}\n";
1685 }
1686 }
1687}
1688
1689
1690//void LatexGenerator::writeLatexLabel(const QCString &clName,const QCString &anchor)
1691//{
1692// writeDoxyAnchor(0,clName,anchor,0);
1693//}
1694
1696{
1697 if (!s1.isEmpty())
1698 {
1699 m_t << "\\index{";
1701 m_t << "@{";
1703 m_t << "}";
1704 if (!s2.isEmpty())
1705 {
1706 m_t << "!";
1708 m_t << "@{";
1710 m_t << "}";
1711 }
1712 m_t << "}";
1713 }
1714}
1715
1716
1718{
1719 bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
1720 bool usePDFLatex = Config_getBool(USE_PDFLATEX);
1721 if (usePDFLatex && pdfHyperlinks)
1722 {
1723 m_t << "\\hypertarget{" << stripPath(lab) << "}{}";
1724 }
1725 m_t << "\\";
1726 if (Config_getBool(COMPACT_LATEX))
1727 {
1728 switch(type.level())
1729 {
1730 case SectionType::Page: m_t << "doxysubsection"; break;
1731 case SectionType::Section: m_t << "doxysubsubsection"; break;
1732 case SectionType::Subsection: m_t << "doxysubsubsubsection"; break;
1733 case SectionType::Subsubsection: m_t << "doxysubsubsubsubsection"; break;
1734 case SectionType::Paragraph: m_t << "doxysubsubsubsubsubsection"; break;
1735 case SectionType::Subparagraph: m_t << "doxysubsubsubsubsubsubsection"; break;
1736 case SectionType::Subsubparagraph: m_t << "doxysubsubsubsubsubsubsection"; break;
1737 default: ASSERT(0); break;
1738 }
1739 m_t << "{";
1740 }
1741 else
1742 {
1743 switch(type.level())
1744 {
1745 case SectionType::Page: m_t << "doxysection"; break;
1746 case SectionType::Section: m_t << "doxysubsection"; break;
1747 case SectionType::Subsection: m_t << "doxysubsubsection"; break;
1748 case SectionType::Subsubsection: m_t << "doxysubsubsubsection"; break;
1749 case SectionType::Paragraph: m_t << "doxysubsubsubsubsection"; break;
1750 case SectionType::Subparagraph: m_t << "doxysubsubsubsubsubsection"; break;
1751 case SectionType::Subsubparagraph: m_t << "doxysubsubsubsubsubsubsection"; break;
1752 default: ASSERT(0); break;
1753 }
1754 m_t << "{";
1755 }
1756}
1757
1759{
1760 m_t << "}\\label{" << lab << "}\n";
1761}
1762
1763
1765{
1767 m_codeGen->insideTabbing(), // insideTabbing
1768 false, // insidePre
1769 false, // insideItem
1770 m_codeGen->usedTableLevel()>0, // insideTable
1771 false // keepSpaces
1772 );
1773}
1774
1776{
1777 char cs[2];
1778 cs[0]=c;
1779 cs[1]=0;
1780 docify(cs);
1781}
1782
1784{
1785 //if (Config_getBool(COMPACT_LATEX)) m_t << "\\doxysubsubsection"; else m_t << "\\doxysubsection";
1786 //m_t << "{";
1787}
1788
1790 const QCString &fileName,const QCString &)
1791{
1793}
1794
1795
1797{
1798 if (indent==0)
1799 {
1800 m_t << "\\begin{tabbing}\n";
1801 m_t << "xx\\=xx\\=xx\\=xx\\=xx\\=xx\\=xx\\=xx\\=xx\\=\\kill\n";
1802 m_codeGen->setInsideTabbing(true);
1803 }
1804 m_indent=indent;
1805}
1806
1808{
1809 if (indent==0)
1810 {
1811 m_t << "\n" << "\\end{tabbing}";
1812 m_codeGen->setInsideTabbing(false);
1813 }
1814 m_indent=indent;
1815}
1816
1818{
1820 {
1821 m_t << "{\\footnotesize ";
1822 }
1823}
1824
1826{
1828 {
1829 m_t << "}\\\\";
1830 }
1831}
1832
1834{
1835 //printf("LatexGenerator::startMemberItem(%d)\n",annType);
1836 if (!m_codeGen->insideTabbing())
1837 {
1838 m_t << "\\item \n";
1840 }
1841}
1842
1844{
1845 if (m_codeGen->insideTabbing())
1846 {
1847 m_t << "\\\\";
1848 }
1850 m_t << "\n";
1851}
1852
1854{
1855 if (!m_codeGen->insideTabbing())
1856 {
1857 m_t << "\\begin{DoxyCompactList}\\small\\item\\em ";
1858 }
1859 else
1860 {
1861 for (int i=0;i<m_indent+2;i++) m_t << "\\>";
1862 m_t << "{\\em ";
1863 }
1864}
1865
1867{
1868 if (!m_codeGen->insideTabbing())
1869 {
1870 //m_t << "\\item\\end{DoxyCompactList}";
1871 m_t << "\\end{DoxyCompactList}";
1872 }
1873 else
1874 {
1875 m_t << "}\\\\\n";
1876 }
1877}
1878
1879
1881{
1882 //printf("writeNonBreakableSpace()\n");
1883 if (m_codeGen->insideTabbing())
1884 {
1885 m_t << "\\>";
1886 }
1887 else
1888 {
1889 m_t << "~";
1890 }
1891}
1892
1893// ----------------------------------------------
1894// nesting of functions below:
1895// startDescTable()
1896// - startDescTableRow()
1897// - startDescTableTitle()
1898// - endDescTableTitle()
1899// - startDescTableData()
1900// - endDescTableData()
1901// - endDescTableRow()
1902// - startDescTableRow()
1903// - ...
1904// - endDescTableRow()
1905// endDescTable()
1906
1907void LatexGenerator::startDescTable(const QCString &title,const bool hasInits)
1908{
1909 m_codeGen->incUsedTableLevel();
1910 m_t << "\\begin{DoxyEnumFields}[" << (hasInits?3:2) << "]{" << title << "}\n";
1911}
1912
1914{
1915 m_codeGen->decUsedTableLevel();
1916 m_t << "\\end{DoxyEnumFields}\n";
1917}
1918
1920{
1921 // this is needed to prevent the \hypertarget, \label, and \index commands from messing up
1922 // the row height (based on http://tex.stackexchange.com/a/186102)
1923 m_t << "\\raisebox{\\heightof{T}}[0pt][0pt]{";
1924}
1925
1929
1931{
1932 m_t << "}";
1933}
1934
1938
1940{
1941 m_t << "&";
1942}
1943
1947
1949{
1950 m_t << "&";
1951}
1952
1954{
1955 m_t << "\\\\\n\\hline\n\n";
1956}
1957
1961
1962
1964{
1965 if (!m_codeGen->insideTabbing())
1966 {
1967 m_t << "\\begin{DoxyCompactItemize}\n";
1968 }
1969}
1970
1972{
1973 //printf("LatexGenerator::endMemberList(%d)\n",m_codeGen->InsideTabbing());
1974 if (!m_codeGen->insideTabbing())
1975 {
1976 m_t << "\\end{DoxyCompactItemize}\n";
1977 }
1978}
1979
1980
1982{
1983 if (hasHeader) m_t << "\\begin{Indent}";
1984 m_t << "\\textbf{ ";
1985 // changed back to rev 756 due to bug 660501
1986 //if (Config_getBool(COMPACT_LATEX))
1987 //{
1988 // m_t << "\\doxysubparagraph*{";
1989 //}
1990 //else
1991 //{
1992 // m_t << "\\doxyparagraph*{";
1993 //}
1994}
1995
1997{
1998 // changed back to rev 756 due to bug 660501
1999 m_t << "}\\par\n";
2000 //m_t << "}\n";
2001}
2002
2004{
2005 m_t << "{\\em ";
2006}
2007
2009{
2010 m_t << "}";
2011}
2012
2016
2018{
2019 if (hasHeader)m_t << "\\end{Indent}";
2020 m_t << "\n";
2021}
2022
2024{
2025 m_t << "\n" << "\n";
2026}
2027
2032
2036
2041
2045
2050
2054
2059
2063
2068
2070{
2071 m_t << "\\begin{Desc}\n\\item[";
2072 docify(theTranslator->trExamples());
2073 m_t << "]";
2074}
2075
2077{
2078 m_t << "\\end{Desc}\n";
2079}
2080
2082{
2083 /* start of ParameterType ParameterName list */
2084 if (openBracket) m_t << "(";
2085 m_t << "\\begin{DoxyParamCaption}";
2086}
2087
2091
2093{
2094 m_t << "\\item[{";
2095 if (!first && !key.isEmpty()) docify(key);
2096}
2097
2099{
2100 m_t << "}]";
2101}
2102
2103void LatexGenerator::startParameterName(bool /*oneArgOnly*/)
2104{
2105 m_t << "{";
2106}
2107
2109{
2110 m_t << "}";
2111}
2112
2114{
2115 m_t << "{";
2116}
2117
2118void LatexGenerator::endParameterExtra(bool last,bool /*emptyList*/,bool closeBracket)
2119{
2120 m_t << "}";
2121 if (last)
2122 {
2123 m_t << "\\end{DoxyParamCaption}";
2124 if (closeBracket) m_t << ")";
2125 }
2126}
2127
2128void LatexGenerator::exceptionEntry(const QCString &prefix,bool closeBracket)
2129{
2130 if (!prefix.isEmpty())
2131 {
2132 m_t << " " << prefix << "(";
2133 }
2134 else if (closeBracket)
2135 {
2136 m_t << ")";
2137 }
2138 m_t << " ";
2139}
2140
2141void LatexGenerator::writeDoc(const IDocNodeAST *ast,const Definition *ctx,const MemberDef *,int)
2142{
2143 const DocNodeAST *astImpl = dynamic_cast<const DocNodeAST*>(ast);
2144 if (astImpl)
2145 {
2147 ctx?ctx->getDefFileExtension():QCString(""),
2149 std::visit(visitor,astImpl->root);
2150 }
2151}
2152
2154{
2155 m_t << "\\begin{Desc}\n\\item[";
2156 docify(header);
2157 m_t << "]";
2158 m_t << "\\begin{description}\n";
2159}
2160
2162{
2163 m_t << "\\item[{\\em ";
2164}
2165
2169
2171{
2172 m_t << "} : {\\em ";
2173}
2174
2176{
2177 m_t << "}]";
2178}
2179
2183
2187
2189{
2190 m_t << "\\end{description}\n";
2191 m_t << "\\end{Desc}\n";
2192}
2193
2195{
2196 if (Config_getBool(COMPACT_LATEX))
2197 {
2198 m_t << "\\doxyparagraph*{";
2199 }
2200 else
2201 {
2202 m_t << "\\doxy" << QCString("sub").repeat(m_hierarchyLevel + 1) << "section*{";
2203 }
2204}
2205
2207{
2208 m_t << "}\n";
2209}
2210
2212{
2213 if (m_codeGen->insideTabbing())
2214 {
2215 m_t << "\\\\\n";
2216 }
2217 else
2218 {
2219 m_t << "\\newline\n";
2220 }
2221}
2222
2224{
2225 m_codeGen->incUsedTableLevel();
2226 if (isEnum)
2227 {
2228 m_t << "\\begin{DoxyEnumFields}{";
2229 docify(theTranslator->trEnumerationValues());
2230 }
2231 else
2232 {
2233 m_t << "\\begin{DoxyFields}{";
2234 docify(theTranslator->trCompoundMembers());
2235 }
2236 m_t << "}\n";
2237 m_insideTableEnv=true;
2238}
2239
2241{
2242 m_insideTableEnv=false;
2243 m_codeGen->decUsedTableLevel();
2244 if (isEnum)
2245 {
2246 m_t << "\\end{DoxyEnumFields}\n";
2247 }
2248 else
2249 {
2250 m_t << "\\end{DoxyFields}\n";
2251 }
2252}
2253
2255{
2256 m_codeGen->setInsideTabbing(true); // to prevent \+ from causing unwanted breaks
2257}
2258
2260{
2261 m_t << "&\n";
2262 m_codeGen->setInsideTabbing(false);
2263}
2264
2266{
2267 m_codeGen->setInsideTabbing(true); // to prevent \+ from causing unwanted breaks
2268}
2269
2271{
2272 m_t << "&\n";
2273 m_codeGen->setInsideTabbing(false);
2274}
2275
2279
2281{
2282 m_t << "\\\\\n\\hline\n\n";
2283}
2284
2286{
2287 m_t << "\\hspace{0.3cm}";
2288}
2289
2290void LatexGenerator::writeLabel(const QCString &l,bool isLast)
2291{
2292 m_t << "{\\ttfamily [" << l << "]}";
2293 if (!isLast) m_t << ", ";
2294}
2295
2297{
2298}
2299
2301 const QCString &/*id*/,const QCString &ref,
2302 const QCString &file, const QCString &anchor,
2303 const QCString &title, const QCString &name)
2304{
2305 if (Config_getBool(COMPACT_LATEX))
2306 {
2307 m_t << "\\doxyparagraph*{";
2308 }
2309 else
2310 {
2311 m_t << "\\doxy" << QCString("sub").repeat(m_hierarchyLevel + 1) << "section*{";
2312 }
2313 m_t << theTranslator->trInheritedFrom(convertToLaTeX(title,m_codeGen->insideTabbing()),
2314 objectLinkToString(ref, file, anchor, name, m_codeGen->insideTabbing(), m_disableLinks));
2315 m_t << "}\n";
2316}
2317
2319{
2320 if (localToc.isLatexEnabled())
2321 {
2322 int maxLevel = localToc.latexLevel() + m_hierarchyLevel;
2323 m_t << "\\etocsetnexttocdepth{" << maxLevel << "}\n";
2324 m_t << "\\localtableofcontents\n";
2325 }
2326}
2327
2328//--------------------------------------------------------------------------------------------------
2329
2331{
2332 // User-specified packages
2333 const StringVector &extraPackages = Config_getList(EXTRA_PACKAGES);
2334 if (!extraPackages.empty())
2335 {
2336 t << "% Packages requested by user\n";
2337 for (const auto &pkgName : extraPackages)
2338 {
2339 if ((pkgName[0] == '[') || (pkgName[0] == '{'))
2340 t << "\\usepackage" << pkgName.c_str() << "\n";
2341 else
2342 t << "\\usepackage{" << pkgName.c_str() << "}\n";
2343 }
2344 t << "\n";
2345 }
2346}
2347
2349{
2350 unsigned char minus[4]; // Superscript minus
2351 unsigned char sup2[3]; // Superscript two
2352 unsigned char sup3[3];
2353 minus[0]= 0xE2;
2354 minus[1]= 0x81;
2355 minus[2]= 0xBB;
2356 minus[3]= 0;
2357 sup2[0]= 0xC2;
2358 sup2[1]= 0xB2;
2359 sup2[2]= 0;
2360 sup3[0]= 0xC2;
2361 sup3[1]= 0xB3;
2362 sup3[2]= 0;
2363
2364 t << "\\ifPDFTeX\n";
2365 t << "\\usepackage{newunicodechar}\n";
2366 // taken from the newunicodechar package and removed the warning message
2367 // actually forcing to redefine the unicode character
2368 t << " \\makeatletter\n"
2369 " \\def\\doxynewunicodechar#1#2{%\n"
2370 " \\@tempswafalse\n"
2371 " \\edef\\nuc@tempa{\\detokenize{#1}}%\n"
2372 " \\if\\relax\\nuc@tempa\\relax\n"
2373 " \\nuc@emptyargerr\n"
2374 " \\else\n"
2375 " \\edef\\@tempb{\\expandafter\\@car\\nuc@tempa\\@nil}%\n"
2376 " \\nuc@check\n"
2377 " \\if@tempswa\n"
2378 " \\@namedef{u8:\\nuc@tempa}{#2}%\n"
2379 " \\fi\n"
2380 " \\fi\n"
2381 " }\n"
2382 " \\makeatother\n";
2383
2384 t << " \\doxynewunicodechar{" << minus << "}{${}^{-}$}% Superscript minus\n"
2385 " \\doxynewunicodechar{" << sup2 << "}{${}^{2}$}% Superscript two\n"
2386 " \\doxynewunicodechar{" << sup3 << "}{${}^{3}$}% Superscript three\n"
2387 "\n";
2388 t << "\\fi\n";
2389}
2390
2392 bool insideTabbing,bool insidePre,bool insideItem,bool insideTable,bool keepSpaces, const bool retainNewline)
2393{
2394 if (str.isEmpty()) return;
2395 bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
2396 //printf("filterLatexString(%s) insideTabbing=%d\n",qPrint(str),insideTabbing);
2397 const char *p = str.data();
2398 const char *q = nullptr;
2399 unsigned char pc='\0';
2400
2401 while (*p)
2402 {
2403 unsigned char c=static_cast<unsigned char>(*p++);
2404
2405 if (insidePre)
2406 {
2407 switch(c)
2408 {
2409 case 0xef: // handle U+FFFD i.e. "Replacement character" caused by octal: 357 277 275 / hexadecimal 0xef 0xbf 0xbd
2410 // the LaTeX command \ucr has been defined in doxygen.sty
2411 if (static_cast<unsigned char>(*(p)) == 0xbf && static_cast<unsigned char>(*(p+1)) == 0xbd)
2412 {
2413 t << "{\\ucr}";
2414 p += 2;
2415 }
2416 else
2417 t << static_cast<char>(c);
2418 break;
2419 case '\\': t << "\\(\\backslash\\)"; break;
2420 case '{': t << "\\{"; break;
2421 case '}': t << "\\}"; break;
2422 case '_': t << "\\_"; break;
2423 case '&': t << "\\&"; break;
2424 case '%': t << "\\%"; break;
2425 case '#': t << "\\#"; break;
2426 case '$': t << "\\$"; break;
2427 case '"': t << "\"{}"; break;
2428 case '-': t << "-\\/"; break;
2429 case '^': insideTable ? t << "\\string^" : t << static_cast<char>(c); break;
2430 case '~': t << "\\string~"; break;
2431 case '\n': if (retainNewline) t << "\\newline"; else t << ' ';
2432 break;
2433 case ' ': if (keepSpaces) t << "~"; else t << ' ';
2434 break;
2435 default:
2436 if (c<32) t << ' '; // non printable control character
2437 else t << static_cast<char>(c);
2438 break;
2439 }
2440 }
2441 else
2442 {
2443 switch(c)
2444 {
2445 case 0xef: // handle U+FFFD i.e. "Replacement character" caused by octal: 357 277 275 / hexadecimal 0xef 0xbf 0xbd
2446 // the LaTeX command \ucr has been defined in doxygen.sty
2447 if (static_cast<unsigned char>(*(p)) == 0xbf && static_cast<unsigned char>(*(p+1)) == 0xbd)
2448 {
2449 t << "{\\ucr}";
2450 p += 2;
2451 }
2452 else
2453 t << static_cast<char>(c);
2454 break;
2455 case '#': t << "\\#"; break;
2456 case '$': t << "\\$"; break;
2457 case '%': t << "\\%"; break;
2458 case '^': processEntity(t,pdfHyperlinks,"$^\\wedge$","\\string^"); break;
2459 case '&': {
2460 // possibility to have a special symbol
2461 q = p;
2462 int cnt = 2; // we have to count & and ; as well
2463 while ((*q >= 'a' && *q <= 'z') || (*q >= 'A' && *q <= 'Z') || (*q >= '0' && *q <= '9'))
2464 {
2465 cnt++;
2466 q++;
2467 }
2468 if (*q == ';')
2469 {
2470 --p; // we need & as well
2473 {
2474 p++;
2475 t << "\\&";
2476 }
2477 else
2478 {
2480 q++;
2481 p = q;
2482 }
2483 }
2484 else
2485 {
2486 t << "\\&";
2487 }
2488 }
2489 break;
2490 case '*': processEntity(t,pdfHyperlinks,"$\\ast$","*"); break;
2491 case '_': if (!insideTabbing) t << "\\+";
2492 t << "\\_";
2493 if (!insideTabbing) t << "\\+";
2494 break;
2495 case '{': t << "\\{"; break;
2496 case '}': t << "\\}"; break;
2497 case '<': t << "$<$"; break;
2498 case '>': t << "$>$"; break;
2499 case '|': processEntity(t,pdfHyperlinks,"$\\vert$","|"); break;
2500 case '~': processEntity(t,pdfHyperlinks,"$\\sim$","\\string~"); break;
2501 case '[': if (Config_getBool(PDF_HYPERLINKS) || insideItem)
2502 t << "\\mbox{[}";
2503 else
2504 t << "[";
2505 break;
2506 case ']': if (pc=='[') t << "$\\,$";
2507 if (Config_getBool(PDF_HYPERLINKS) || insideItem)
2508 t << "\\mbox{]}";
2509 else
2510 t << "]";
2511 break;
2512 case '-': t << "-\\/";
2513 break;
2514 case '\\': t << "\\textbackslash{}";
2515 break;
2516 case '"': t << "\"{}";
2517 break;
2518 case '`': t << "\\`{}";
2519 break;
2520 case '\'': t << "\\textquotesingle{}";
2521 break;
2522 case '\n': if (retainNewline) t << "\\newline"; else t << ' ';
2523 break;
2524 case ' ': if (keepSpaces) { if (insideTabbing) t << "\\>"; else t << '~'; } else t << ' ';
2525 break;
2526
2527 default:
2528 //if (!insideTabbing && forceBreaks && c!=' ' && *p!=' ')
2529 if (!insideTabbing &&
2530 ((c>='A' && c<='Z' && pc!=' ' && !(pc>='A' && pc <= 'Z') && pc!='\0' && *p) || (c==':' && pc!=':') || (pc=='.' && isId(c)))
2531 )
2532 {
2533 t << "\\+";
2534 }
2535 if (c<32)
2536 {
2537 t << ' '; // non-printable control character
2538 }
2539 else
2540 {
2541 t << static_cast<char>(c);
2542 }
2543 }
2544 }
2545 pc = c;
2546 }
2547}
2548
2549QCString convertToLaTeX(const QCString &s,bool insideTabbing,bool keepSpaces)
2550{
2551 TextStream t;
2552 filterLatexString(t,s,insideTabbing,false,false,false,keepSpaces);
2553 return t.str();
2554}
2555
2557{
2558 //printf("latexEscapeLabelName(%s)\n",qPrint(s));
2559 if (s.isEmpty()) return s;
2561 TextStream t;
2562 const char *p=s.data();
2563 char c = 0;
2564 while ((c=*p++))
2565 {
2566 switch (c)
2567 {
2568 case '|': t << "\\texttt{\"|}"; break;
2569 case '!': t << "\"!"; break;
2570 case '@': t << "\"@"; break;
2571 case '%': t << "\\%"; break;
2572 case '{': t << "\\lcurly{}"; break;
2573 case '}': t << "\\rcurly{}"; break;
2574 case '~': t << "````~"; break; // to get it a bit better in index together with other special characters
2575 // NOTE: adding a case here, means adding it to while below as well!
2576 default:
2577 {
2578 int i=0;
2579 // collect as long string as possible, before handing it to docify
2580 tmp[i++]=c;
2581 while ((c=*p) && c!='@' && c!='[' && c!=']' && c!='!' && c!='{' && c!='}' && c!='|')
2582 {
2583 tmp[i++]=c;
2584 p++;
2585 }
2586 tmp[i]=0;
2587 filterLatexString(t,tmp,
2588 true, // insideTabbing
2589 false, // insidePre
2590 false, // insideItem
2591 false, // insideTable
2592 false // keepSpaces
2593 );
2594 }
2595 break;
2596 }
2597 }
2598 return t.str();
2599}
2600
2602{
2603 //printf("latexEscapeIndexChars(%s)\n",qPrint(s));
2604 if (s.isEmpty()) return s;
2606 TextStream t;
2607 const char *p=s.data();
2608 char c = 0;
2609 while ((c=*p++))
2610 {
2611 switch (c)
2612 {
2613 case '!': t << "\"!"; break;
2614 case '"': t << "\"\""; break;
2615 case '@': t << "\"@"; break;
2616 case '|': t << "\\texttt{\"|}"; break;
2617 case '[': t << "["; break;
2618 case ']': t << "]"; break;
2619 case '{': t << "\\lcurly{}"; break;
2620 case '}': t << "\\rcurly{}"; break;
2621 // NOTE: adding a case here, means adding it to while below as well!
2622 default:
2623 {
2624 int i=0;
2625 // collect as long string as possible, before handing it to docify
2626 tmp[i++]=c;
2627 while ((c=*p) && c!='"' && c!='@' && c!='[' && c!=']' && c!='!' && c!='{' && c!='}' && c!='|')
2628 {
2629 tmp[i++]=c;
2630 p++;
2631 }
2632 tmp[i]=0;
2633 filterLatexString(t,tmp,
2634 true, // insideTabbing
2635 false, // insidePre
2636 false, // insideItem
2637 false, // insideTable
2638 false // keepSpaces
2639 );
2640 }
2641 break;
2642 }
2643 }
2644 return t.str();
2645}
2646
2648{
2649 if (s.isEmpty()) return s;
2650 TextStream t;
2651 const char *p=s.data();
2652 char c = 0;
2653 while ((c=*p++))
2654 {
2655 switch (c)
2656 {
2657 case '\\': t << "\\textbackslash{}"; break;
2658 case '{': t << "\\{"; break;
2659 case '}': t << "\\}"; break;
2660 case '_': t << "\\_"; break;
2661 case '%': t << "\\%"; break;
2662 case '&': t << "\\&"; break;
2663 case '#': t << "\\#"; break;
2664 case '$': t << "\\$"; break;
2665 case '^': t << "\\string^"; break;
2666 case '~': t << "\\string~"; break;
2667 default:
2668 t << c;
2669 break;
2670 }
2671 }
2672 return t.str();
2673}
2674
2676{
2677 constexpr auto hex = "0123456789ABCDEF";
2678 if (s.isEmpty()) return s;
2679 TextStream t;
2680 const char *p=s.data();
2681 char c = 0;
2682 while ((c=*p++))
2683 {
2684 switch (c)
2685 {
2686 case '#': t << "\\#"; break;
2687 case '%': t << "\\%"; break;
2688 case '\\': t << "\\\\"; break;
2689 default:
2690 if (c<0)
2691 {
2692 unsigned char id = static_cast<unsigned char>(c);
2693 t << "\\%" << hex[id>>4] << hex[id&0xF];
2694 }
2695 else
2696 {
2697 t << c;
2698 }
2699 break;
2700 }
2701 }
2702 return t.str();
2703}
2704
2705
constexpr auto prefix
Definition anchor.cpp:44
QCString latexBibFiles()
lists the bibtex cite files in a comma separated list
Definition cite.cpp:559
static CitationManager & instance()
Definition cite.cpp:80
bool isEmpty() const
return TRUE if there are no citations.
Definition cite.cpp:111
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:1460
DocNodeVariant root
Definition docnode.h:1481
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:49
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:359
void endIndexKey() override
void endInlineMemberDoc() override
void startProjectNumber() override
Definition latexgen.cpp:731
void cleanup() override
Definition latexgen.cpp:676
void endPageRef(const QCString &, const QCString &) override
void endSection(const QCString &, SectionType) override
void startIndexSection(IndexSection) override
Definition latexgen.cpp:912
void endParameterList() override
void endMemberDescription() override
std::unique_ptr< OutputCodeList > m_codeList
Definition latexgen.h:327
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 endMemberGroupHeader() override
void docify(const QCString &text) override
void startAnonTypeScope(int) override
void endPlainFile() override
Definition latexgen.h:315
void startDoxyAnchor(const QCString &, const QCString &, const QCString &, const QCString &, const QCString &) override
static void writeFooterFile(TextStream &t)
Definition latexgen.cpp:694
void startParameterList(bool) override
void endMemberDoc(bool) override
void endConstraintType() override
void startDescTableRow() override
void endAnonTypeScope(int) override
QCString m_relPath
Definition latexgen.h:324
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:700
void endTitleHead(const QCString &, const QCString &name) override
void startGroupHeader(int) override
void endMemberHeader() override
OutputType type() const override
Definition latexgen.h:114
void endIndexItem(const QCString &ref, const QCString &file) 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:330
void startInlineMemberDoc() override
void writeAnchor(const QCString &fileName, const QCString &name) override
void startCallGraph() override
void endMemberList() override
void endFile() override
Definition latexgen.cpp:720
void startExamples() override
LatexGenerator & operator=(const LatexGenerator &)
Definition latexgen.cpp:339
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:314
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:323
void writeLocalToc(const SectionRefs &sr, const LocalToc &lt) override
void startFile(const QCString &name, const QCString &manName, const QCString &title, int id, int hierarchyLevel) override
Definition latexgen.cpp:706
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:328
void endMemberGroup(bool) override
void startMemberDescription(const QCString &, const QCString &, bool) override
void startMemberItem(const QCString &, MemberItemType, const QCString &) override
bool m_firstDescItem
Definition latexgen.h:322
static void writeHeaderFile(TextStream &t)
Definition latexgen.cpp:688
void endParagraph() override
void addLabel(const QCString &, const QCString &) override
bool m_insideTableEnv
Definition latexgen.h:329
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:630
void startMemberGroupHeader(bool) override
bool m_templateMemberItem
Definition latexgen.h:326
int latexLevel() const
Definition types.h:621
bool isLatexEnabled() const
Definition types.h:616
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.
class that represents a list of constant references to sections.
Definition section.h:102
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
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:1357
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:782
QCString latexEscapePDFString(const QCString &s)
QCString convertToLaTeX(const QCString &s, bool insideTabbing, bool keepSpaces)
static QCString makeIndex()
Definition latexgen.cpp:764
QCString latexFilterURL(const QCString &s)
static void writeLatexMakefile()
Definition latexgen.cpp:364
static const SelectionMarkerInfo latexMarkerInfo
Definition latexgen.cpp:55
static QCString extraLatexStyleSheet()
Definition latexgen.cpp:736
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:500
static void writeDefaultStyleSheet(TextStream &t)
Definition latexgen.cpp:683
void writeExtraLatexPackages(TextStream &t)
static QCString substituteLatexKeywords(const QCString &file, const QCString &str, const QCString &title)
Definition latexgen.cpp:796
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:7356
void checkBlocks(const QCString &s, const QCString fileName, const SelectionMarkerInfo &markerInfo)
Definition util.cpp:6998
QCString stripPath(const QCString &s)
Definition util.cpp:5457
QCString removeEmptyLines(const QCString &s)
Definition util.cpp:7062
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:6885
QCString substituteKeywords(const QCString &file, const QCString &s, const KeywordSubstitutionList &keywords)
Definition util.cpp:3564
QCString relativePathToRoot(const QCString &name)
Definition util.cpp:4088
void clearSubDirs(const Dir &d)
Definition util.cpp:4176
bool found
Definition util.cpp:984
QCString fileToString(const QCString &name, bool filter, bool isSourceCode)
Definition util.cpp:1441
QCString stripExtensionGeneral(const QCString &fName, const QCString &ext)
Definition util.cpp:5420
void createSubDirs(const Dir &d)
Definition util.cpp:4149
bool checkExtension(const QCString &fName, const QCString &ext)
Definition util.cpp:5403
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:6335
A bunch of utility functions.
bool isId(int c)
Definition util.h:208