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 "outputlist.h"
48#include "moduledef.h"
49
54static const SelectionMarkerInfo latexMarkerInfo = { '%', "%%BEGIN ",8 ,"%%END ",6, "",0 };
55
56static QCString substituteLatexKeywords(const QCString &file, const QCString &str, const QCString &title);
57
59 : m_t(t), m_relPath(relPath), m_sourceFileName(sourceFileName)
60{
61}
62
66
68{
69 m_relPath = path;
70}
71
76
78{
79 if (!str.isEmpty())
80 {
81 const char *p=str.data();
82 char c = 0;
83 //char cs[5];
84 int tabSize = Config_getInt(TAB_SIZE);
85 static THREAD_LOCAL char *result = nullptr;
86 static THREAD_LOCAL int lresult = 0;
87 if (m_hide) // only update column count
88 {
90 }
91 else // actually output content and keep track of m_col
92 {
93 while ((c=*p))
94 {
95 switch(c)
96 {
97 case 0x0c: p++; // remove ^L
98 break;
99 case ' ': if (m_col>=m_stripIndentAmount)
100 {
101 *m_t << (m_doxyCodeLineOpen ? "\\ " : " ");
102 }
103 m_col++;
104 p++;
105 break;
106 case '^': *m_t <<"\\string^";
107 m_col++;
108 p++;
109 break;
110 case '`': *m_t <<"\\`{}";
111 m_col++;
112 p++;
113 break;
114 case '\t': {
115 int spacesToNextTabStop = tabSize - (m_col%tabSize);
116 while (spacesToNextTabStop--)
117 {
119 {
120 *m_t << (m_doxyCodeLineOpen ? "\\ " : " ");
121 }
122 m_col++;
123 }
124 p++;
125 }
126 break;
127 case '\n': *m_t << '\n';
128 m_col=0;
129 p++;
130 break;
131 default:
132 {
133 int i=0;
134
135#undef COPYCHAR
136// helper macro to copy a single utf8 character, dealing with multibyte chars.
137#define COPYCHAR() do { \
138 int bytes = getUTF8CharNumBytes(c); \
139 if (lresult < (i + bytes + 1)) \
140 { \
141 lresult += 512; \
142 result = static_cast<char *>(realloc(result, lresult)); \
143 } \
144 for (int j=0; j<bytes && *p; j++) \
145 { \
146 result[i++]=*p++; \
147 } \
148 m_col++; \
149 } while(0)
150
151 // gather characters until we find whitespace or another special character
152 COPYCHAR();
153 while ((c=*p) &&
154 c!=0x0c && c!='\t' && c!='\n' && c!=' ' && c!='^'
155 )
156 {
157 COPYCHAR();
158 }
159 result[i]=0; // add terminator
160 filterLatexString(*m_t,result,
161 m_insideTabbing, // insideTabbing
162 true, // insidePre
163 false, // insideItem
164 m_usedTableLevel>0, // insideTable
165 false // keepSpaces
166 );
167 }
168 break;
169 }
170 }
171 }
172 }
173}
174
179
184
186{
187 m_hide = false;
188}
189
191{
192 m_stripIndentAmount = amount;
193}
194
196 const QCString &ref,const QCString &f,
197 const QCString &anchor,const QCString &name,
198 const QCString &)
199{
200 if (m_hide) return;
201 bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
202 bool usePDFLatex = Config_getBool(USE_PDFLATEX);
203 size_t l = name.length();
204 if (ref.isEmpty() && usePDFLatex && pdfHyperlinks)
205 {
206 *m_t << "\\doxymbox{\\hyperlink{";
207 if (!f.isEmpty()) *m_t << stripPath(f);
208 if (!f.isEmpty() && !anchor.isEmpty()) *m_t << "_";
209 if (!anchor.isEmpty()) *m_t << anchor;
210 *m_t << "}{";
211 codify(name);
212 *m_t << "}}";
213 }
214 else
215 {
216 codify(name);
217 }
218 m_col+=l;
219}
220
221void LatexCodeGenerator::writeLineNumber(const QCString &ref,const QCString &fileName,const QCString &anchor,int l,bool writeLineAnchor)
222{
223 if (m_hide) return;
224 bool usePDFLatex = Config_getBool(USE_PDFLATEX);
225 bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
227 {
228 *m_t << "\\DoxyCodeLine{";
230 }
231 if (Config_getBool(SOURCE_BROWSER))
232 {
233 QCString lineNumber;
234 lineNumber.sprintf("%05d",l);
235
236 QCString lineAnchor;
237 if (!m_sourceFileName.isEmpty())
238 {
239 lineAnchor.sprintf("_l%05d",l);
241 }
242 bool showTarget = usePDFLatex && pdfHyperlinks && !lineAnchor.isEmpty() && writeLineAnchor;
243 if (showTarget)
244 {
245 *m_t << "\\Hypertarget{" << stripPath(lineAnchor) << "}";
246 }
247 if (!fileName.isEmpty())
248 {
249 writeCodeLink(CodeSymbolType::Default,ref,fileName,anchor,lineNumber,QCString());
250 }
251 else
252 {
253 codify(lineNumber);
254 }
255 *m_t << "\\ ";
256 }
257 else
258 {
259 QCString lineNumber;
260 lineNumber.sprintf("%05d",l);
261 codify(lineNumber);
262 *m_t << "\\ ";
263 }
264 m_col=0;
265}
266
267
269{
270 if (m_hide) return;
271 m_col=0;
273 {
274 *m_t << "\\DoxyCodeLine{";
276 }
277}
278
280{
281 if (m_hide) return;
283 {
284 *m_t << "}";
286 }
287 codify("\n");
288}
289
291{
292 if (m_hide) return;
293 *m_t << "\\textcolor{" << name << "}{";
294}
295
297{
298 if (m_hide) return;
299 *m_t << "}";
300}
301
303{
304 *m_t << "\n\\begin{" << style << "}{" << m_usedTableLevel << "}\n";
305}
306
308{
309 //endCodeLine checks is there is still an open code line, if so closes it.
310 bool wasHidden = m_hide;
311 m_hide = false;
312 endCodeLine();
313 m_hide = wasHidden;
314
315 *m_t << "\\end{" << style << "}\n";
316}
317
318
319//-------------------------------
320
327
340
342{
343 if (this!=&og)
344 {
345 m_dir = og.m_dir;
346 m_codeList = std::make_unique<OutputCodeList>(*og.m_codeList);
348 m_codeGen->setTextStream(&m_t);
351 m_relPath = og.m_relPath;
352 m_indent = og.m_indent;
355 }
356 return *this;
357}
358
360
365
367{
368 bool generateBib = !CitationManager::instance().isEmpty();
369 QCString fileName=Config_getString(LATEX_OUTPUT)+"/Makefile";
370 std::ofstream f = Portable::openOutputStream(fileName);
371 if (!f.is_open())
372 {
373 term("Could not open file {} for writing\n",fileName);
374 }
375 TextStream t(&f);
376 // inserted by KONNO Akihisa <konno@researchers.jp> 2002-03-05
377 QCString latex_command = theTranslator->latexCommandName().quoted();
378 QCString mkidx_command = Config_getString(MAKEINDEX_CMD_NAME).quoted();
379 QCString bibtex_command = "bibtex";
380 QCString manual_file = "refman";
381 const int latex_count = 8;
382 // end insertion by KONNO Akihisa <konno@researchers.jp> 2002-03-05
383 t << "LATEX_CMD?=" << latex_command << "\n"
384 << "MKIDX_CMD?=" << mkidx_command << "\n"
385 << "BIBTEX_CMD?=" << bibtex_command << "\n"
386 << "LATEX_COUNT?=" << latex_count << "\n"
387 << "MANUAL_FILE?=" << manual_file << "\n"
388 << "\n";
389 if (!Config_getBool(USE_PDFLATEX)) // use plain old latex
390 {
391 t << "all: $(MANUAL_FILE).dvi\n"
392 << "\n"
393 << "ps: $(MANUAL_FILE).ps\n"
394 << "\n"
395 << "pdf: $(MANUAL_FILE).pdf\n"
396 << "\n"
397 << "ps_2on1: $(MANUAL_FILE).ps\n"
398 << "\n"
399 << "pdf_2on1: $(MANUAL_FILE).pdf\n"
400 << "\n"
401 << "$(MANUAL_FILE).ps: $(MANUAL_FILE).dvi\n"
402 << "\tdvips -o $(MANUAL_FILE).ps $(MANUAL_FILE).dvi\n"
403 << "\n";
404 t << "$(MANUAL_FILE).pdf: $(MANUAL_FILE).ps\n";
405 t << "\tps2pdf $(MANUAL_FILE).ps $(MANUAL_FILE).pdf\n\n";
406 t << "$(MANUAL_FILE).dvi: clean $(MANUAL_FILE).tex doxygen.sty\n"
407 << "\techo \"Running latex...\"\n"
408 << "\t$(LATEX_CMD) $(MANUAL_FILE).tex || \\\n"
409 << "\tif [ $$? != 0 ] ; then \\\n"
410 << "\t \\echo \"Please consult $(MANUAL_FILE).log to see the error messages\" ; \\\n"
411 << "\t false; \\\n"
412 << "\tfi\n"
413 << "\techo \"Running makeindex...\"\n"
414 << "\t$(MKIDX_CMD) $(MANUAL_FILE).idx\n";
415 if (generateBib)
416 {
417 t << "\techo \"Running bibtex...\"\n";
418 t << "\t$(BIBTEX_CMD) $(MANUAL_FILE)\n";
419 t << "\techo \"Rerunning latex....\"\n";
420 t << "\t$(LATEX_CMD) $(MANUAL_FILE).tex || \\\n"
421 << "\tif [ $$? != 0 ] ; then \\\n"
422 << "\t \\echo \"Please consult $(MANUAL_FILE).log to see the error messages\" ; \\\n"
423 << "\t false; \\\n"
424 << "\tfi\n";
425 }
426 t << "\techo \"Rerunning latex....\"\n"
427 << "\t$(LATEX_CMD) $(MANUAL_FILE).tex\n"
428 << "\tlatex_count=$(LATEX_COUNT) ; \\\n"
429 << "\twhile grep -E -s 'Rerun (LaTeX|to get cross-references right|to get bibliographical references right)' $(MANUAL_FILE).log && [ $$latex_count -gt 0 ] ;\\\n"
430 << "\t do \\\n"
431 << "\t echo \"Rerunning latex....\" ;\\\n"
432 << "\t $(LATEX_CMD) $(MANUAL_FILE).tex ; \\\n"
433 << "\t $(LATEX_CMD) $(MANUAL_FILE).tex || \\\n"
434 << "\t if [ $$? != 0 ] ; then \\\n"
435 << "\t \\echo \"Please consult $(MANUAL_FILE).log to see the error messages\" ; \\\n"
436 << "\t false; \\\n"
437 << "\t fi; \\\n"
438 << "\t latex_count=`expr $$latex_count - 1` ;\\\n"
439 << "\t done\n"
440 << "\t$(MKIDX_CMD) $(MANUAL_FILE).idx\n"
441 << "\t$(LATEX_CMD) $(MANUAL_FILE).tex || \\\n"
442 << "\tif [ $$? != 0 ] ; then \\\n"
443 << "\t \\echo \"Please consult $(MANUAL_FILE).log to see the error messages\" ; \\\n"
444 << "\t false; \\\n"
445 << "\tfi\n"
446 << "$(MANUAL_FILE).ps: $(MANUAL_FILE).ps\n"
447 << "\tpsnup -2 $(MANUAL_FILE).ps >$(MANUAL_FILE).ps\n"
448 << "\n"
449 << "$(MANUAL_FILE).pdf: $(MANUAL_FILE).ps\n"
450 << "\tps2pdf $(MANUAL_FILE).ps $(MANUAL_FILE).pdf\n";
451 }
452 else // use pdflatex for higher quality output
453 {
454 t << "all: $(MANUAL_FILE).pdf\n\n"
455 << "pdf: $(MANUAL_FILE).pdf\n\n";
456 t << "$(MANUAL_FILE).pdf: clean $(MANUAL_FILE).tex\n";
457 t << "\t$(LATEX_CMD) $(MANUAL_FILE) || \\\n"
458 << "\tif [ $$? != 0 ] ; then \\\n"
459 << "\t \\echo \"Please consult $(MANUAL_FILE).log to see the error messages\" ; \\\n"
460 << "\t false; \\\n"
461 << "\tfi\n";
462 t << "\t$(MKIDX_CMD) $(MANUAL_FILE).idx\n";
463 if (generateBib)
464 {
465 t << "\t$(BIBTEX_CMD) $(MANUAL_FILE)\n";
466 t << "\t$(LATEX_CMD) $(MANUAL_FILE) || \\\n"
467 << "\tif [ $$? != 0 ] ; then \\\n"
468 << "\t \\echo \"Please consult $(MANUAL_FILE).log to see the error messages\" ; \\\n"
469 << "\t false; \\\n"
470 << "\tfi\n";
471 }
472 t << "\t$(LATEX_CMD) $(MANUAL_FILE) || \\\n"
473 << "\tif [ $$? != 0 ] ; then \\\n"
474 << "\t \\echo \"Please consult $(MANUAL_FILE).log to see the error messages\" ; \\\n"
475 << "\t false; \\\n"
476 << "\tfi\n"
477 << "\tlatex_count=$(LATEX_COUNT) ; \\\n"
478 << "\twhile grep -E -s 'Rerun (LaTeX|to get cross-references right|to get bibliographical references right)' $(MANUAL_FILE).log && [ $$latex_count -gt 0 ] ;\\\n"
479 << "\t do \\\n"
480 << "\t echo \"Rerunning latex....\" ;\\\n"
481 << "\t $(LATEX_CMD) $(MANUAL_FILE) || \\\n"
482 << "\t if [ $$? != 0 ] ; then \\\n"
483 << "\t \\echo \"Please consult $(MANUAL_FILE).log to see the error messages\" ; \\\n"
484 << "\t false; \\\n"
485 << "\t fi; \\\n"
486 << "\t latex_count=`expr $$latex_count - 1` ;\\\n"
487 << "\t done\n"
488 << "\t$(MKIDX_CMD) $(MANUAL_FILE).idx\n"
489 << "\t$(LATEX_CMD) $(MANUAL_FILE) || \\\n"
490 << "\tif [ $$? != 0 ] ; then \\\n"
491 << "\t \\echo \"Please consult $(MANUAL_FILE).log to see the error messages\" ; \\\n"
492 << "\t false; \\\n"
493 << "\tfi\n";
494 }
495
496 t << "\n"
497 << "clean:\n"
498 << "\trm -f "
499 << "*.ps *.dvi *.aux *.toc *.idx *.ind *.ilg *.log *.out *.brf *.blg *.bbl $(MANUAL_FILE).pdf\n";
500}
501
502static void writeMakeBat()
503{
504#if defined(_MSC_VER)
505 QCString dir=Config_getString(LATEX_OUTPUT);
506 QCString fileName=dir+"/make.bat";
507 QCString latex_command = theTranslator->latexCommandName().quoted();
508 QCString mkidx_command = Config_getString(MAKEINDEX_CMD_NAME).quoted();
509 QCString bibtex_command = "bibtex";
510 QCString manual_file = "refman";
511 const int latex_count = 8;
512 bool generateBib = !CitationManager::instance().isEmpty();
513 std::ofstream t = Portable::openOutputStream(fileName);
514 if (!t.is_open())
515 {
516 term("Could not open file {} for writing\n",fileName);
517 }
518 t << "pushd %~dp0\r\n";
519 t << "if not %errorlevel% == 0 goto :end1\r\n";
520 t << "\r\n";
521 t << "set ORG_LATEX_CMD=%LATEX_CMD%\r\n";
522 t << "set ORG_MKIDX_CMD=%MKIDX_CMD%\r\n";
523 t << "set ORG_BIBTEX_CMD=%BIBTEX_CMD%\r\n";
524 t << "set ORG_LATEX_COUNT=%LATEX_COUNT%\r\n";
525 t << "set ORG_MANUAL_FILE=%MANUAL_FILE%\r\n";
526 t << "if \"X\"%LATEX_CMD% == \"X\" set LATEX_CMD=" << latex_command << "\r\n";
527 t << "if \"X\"%MKIDX_CMD% == \"X\" set MKIDX_CMD=" << mkidx_command << "\r\n";
528 t << "if \"X\"%BIBTEX_CMD% == \"X\" set BIBTEX_CMD=" << bibtex_command << "\r\n";
529 t << "if \"X\"%LATEX_COUNT% == \"X\" set LATEX_COUNT=" << latex_count << "\r\n";
530 t << "if \"X\"%MANUAL_FILE% == \"X\" set MANUAL_FILE=" << manual_file << "\r\n";
531 t << "\r\n";
532 t << "del /s /f *.ps *.dvi *.aux *.toc *.idx *.ind *.ilg *.log *.out *.brf *.blg *.bbl %MANUAL_FILE%.pdf\r\n\r\n";
533 t << "\r\n";
534 if (!Config_getBool(USE_PDFLATEX)) // use plain old latex
535 {
536 t << "%LATEX_CMD% %MANUAL_FILE%.tex\r\n";
537 t << "@if ERRORLEVEL 1 goto :error\r\n";
538 t << "echo ----\r\n";
539 t << "%MKIDX_CMD% %MANUAL_FILE%.idx\r\n";
540 if (generateBib)
541 {
542 t << "%BIBTEX_CMD% %MANUAL_FILE%\r\n";
543 t << "echo ----\r\n";
544 t << "\t%LATEX_CMD% %MANUAL_FILE%.tex\r\n";
545 t << "@if ERRORLEVEL 1 goto :error\r\n";
546 }
547 t << "setlocal enabledelayedexpansion\r\n";
548 t << "set count=%LAT#EX_COUNT%\r\n";
549 t << ":repeat\r\n";
550 t << "set content=X\r\n";
551 t << "for /F \"tokens=*\" %%T in ( 'findstr /C:\"Rerun LaTeX\" %MANUAL_FILE%.log' ) do set content=\"%%~T\"\r\n";
552 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";
553 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";
554 t << "if !content! == X goto :skip\r\n";
555 t << "set /a count-=1\r\n";
556 t << "if !count! EQU 0 goto :skip\r\n\r\n";
557 t << "echo ----\r\n";
558 t << "%LATEX_CMD% %MANUAL_FILE%.tex\r\n";
559 t << "@if ERRORLEVEL 1 goto :error\r\n";
560 t << "goto :repeat\r\n";
561 t << ":skip\r\n";
562 t << "endlocal\r\n";
563 t << "%MKIDX_CMD% %MANUAL_FILE%.idx\r\n";
564 t << "%LATEX_CMD% %MANUAL_FILE%.tex\r\n";
565 t << "@if ERRORLEVEL 1 goto :error\r\n";
566 t << "dvips -o %MANUAL_FILE%.ps %MANUAL_FILE%.dvi\r\n";
568 t << " -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite "
569 "-sOutputFile=%MANUAL_FILE%.pdf -c save pop -f %MANUAL_FILE%.ps\r\n";
570 }
571 else // use pdflatex
572 {
573 t << "%LATEX_CMD% %MANUAL_FILE%\r\n";
574 t << "@if ERRORLEVEL 1 goto :error\r\n";
575 t << "echo ----\r\n";
576 t << "%MKIDX_CMD% %MANUAL_FILE%.idx\r\n";
577 if (generateBib)
578 {
579 t << "%BIBTEX_CMD% %MANUAL_FILE%\r\n";
580 t << "%LATEX_CMD% %MANUAL_FILE%\r\n";
581 t << "@if ERRORLEVEL 1 goto :error\r\n";
582 }
583 t << "echo ----\r\n";
584 t << "%LATEX_CMD% %MANUAL_FILE%\r\n";
585 t << "@if ERRORLEVEL 1 goto :error\r\n";
586 t << "\r\n";
587 t << "setlocal enabledelayedexpansion\r\n";
588 t << "set count=%LATEX_COUNT%\r\n";
589 t << ":repeat\r\n";
590 t << "set content=X\r\n";
591 t << "for /F \"tokens=*\" %%T in ( 'findstr /C:\"Rerun LaTeX\" %MANUAL_FILE%.log' ) do set content=\"%%~T\"\r\n";
592 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";
593 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";
594 t << "if !content! == X goto :skip\r\n";
595 t << "set /a count-=1\r\n";
596 t << "if !count! EQU 0 goto :skip\r\n\r\n";
597 t << "echo ----\r\n";
598 t << "%LATEX_CMD% %MANUAL_FILE%\r\n";
599 t << "@if ERRORLEVEL 1 goto :error\r\n";
600 t << "goto :repeat\r\n";
601 t << ":skip\r\n";
602 t << "endlocal\r\n";
603 t << "%MKIDX_CMD% %MANUAL_FILE%.idx\r\n";
604 t << "%LATEX_CMD% %MANUAL_FILE%\r\n";
605 t << "@if ERRORLEVEL 1 goto :error\r\n";
606 }
607 t<< "\r\n";
608 t << "goto :end\r\n";
609 t << ":error\r\n";
610 t << "@echo ===============\r\n";
611 t << "@echo Please consult %MANUAL_FILE%.log to see the error messages\r\n";
612 t << "@echo ===============\r\n";
613 t<< "\r\n";
614 t<< ":end\r\n";
615 t<< "@REM reset environment\r\n";
616 t<< "popd\r\n";
617 t<< "set LATEX_CMD=%ORG_LATEX_CMD%\r\n";
618 t<< "set ORG_LATEX_CMD=\r\n";
619 t<< "set MKIDX_CMD=%ORG_MKIDX_CMD%\r\n";
620 t<< "set ORG_MKIDX_CMD=\r\n";
621 t<< "set BIBTEX_CMD=%ORG_BIBTEX_CMD%\r\n";
622 t<< "set ORG_BIBTEX_CMD=\r\n";
623 t<< "set MANUAL_FILE=%ORG_MANUAL_FILE%\r\n";
624 t<< "set ORG_MANUAL_FILE=\r\n";
625 t<< "set LATEX_COUNT=%ORG_LATEX_COUNT%\r\n";
626 t<< "set ORG_LATEX_COUNT=\r\n";
627 t<< "\r\n";
628 t<< ":end1\r\n";
629#endif
630}
631
633{
634 QCString dname = Config_getString(LATEX_OUTPUT);
635 Dir d(dname.str());
636 if (!d.exists() && !d.mkdir(dname.str()))
637 {
638 term("Could not create output directory {}\n",dname);
639 }
640
641 if (!Config_getString(LATEX_HEADER).isEmpty())
642 {
643 g_header_file=Config_getString(LATEX_HEADER);
645 //printf("g_header='%s'\n",qPrint(g_header));
648 }
649 else
650 {
651 g_header_file = "header.tex";
654 checkBlocks(result,"<default header.tex>",latexMarkerInfo);
655 }
656 if (!Config_getString(LATEX_FOOTER).isEmpty())
657 {
658 g_footer_file=Config_getString(LATEX_FOOTER);
660 //printf("g_footer='%s'\n",qPrint(g_footer));
663 }
664 else
665 {
666 g_footer_file = "footer.tex";
669 checkBlocks(result,"<default footer.tex>",latexMarkerInfo);
670 }
671
673 writeMakeBat();
674
675 createSubDirs(d);
676}
677
679{
680 QCString dname = Config_getString(LATEX_OUTPUT);
681 Dir d(dname.str());
682 clearSubDirs(d);
683}
684
686{
687 t << ResourceMgr::instance().getAsString("doxygen.sty");
688}
689
691{
692 t << "% Latex header for doxygen " << getDoxygenVersion() << "\n";
693 t << ResourceMgr::instance().getAsString("header.tex");
694}
695
697{
698 t << "% Latex footer for doxygen " << getDoxygenVersion() << "\n";
699 t << ResourceMgr::instance().getAsString("footer.tex");
700}
701
703{
704 t << "% stylesheet for doxygen " << getDoxygenVersion() << "\n";
706}
707
708void LatexGenerator::startFile(const QCString &name,bool,const QCString &,const QCString &,int,int hierarchyLevel)
709{
710#if 0
711 setEncoding(Config_getString(LATEX_OUTPUT_ENCODING));
712#endif
713 QCString fileName=name;
714 m_hierarchyLevel = hierarchyLevel;
716 if (!fileName.endsWith(".tex") && !fileName.endsWith(".sty")) fileName+=".tex";
718 m_codeGen->setRelativePath(m_relPath);
719 m_codeGen->setSourceFileName(stripPath(fileName));
720}
721
723{
724 endPlainFile();
725 m_codeGen->setSourceFileName("");
726}
727
728//void LatexGenerator::writeIndex()
729//{
730// startFile("refman.tex");
731//}
732
734{
735 m_t << "\\\\[1ex]\\large ";
736}
737
739{
740 QCString result;
741 const StringVector &extraLatexStyles = Config_getList(LATEX_EXTRA_STYLESHEET);
742 for (const auto &fileName : extraLatexStyles)
743 {
744 if (!fileName.empty())
745 {
746 FileInfo fi(fileName);
747 if (fi.exists())
748 {
749 result += "\\usepackage{";
750 QCString fn = fi.fileName();
752 {
753 // strip the extension, it will be added by the usepackage in the tex conversion process
755 }
756 else
757 {
758 result += fn;
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 /// an extension of the etoc package is required that is only available in the
1301 /// newer version. Providing the updated version to be used with older versions
1302 /// of LaTeX
1303 startPlainFile("etoc_doxygen.sty");
1304 m_t << ResourceMgr::instance().getAsString("etoc_doxygen.sty");
1305 endPlainFile();
1306}
1307
1309{
1310 m_t << "\n" << "\n";
1311}
1312
1314{
1315 m_t << "\n" << "\n";
1316}
1317
1319{
1320 m_t << text;
1321}
1322
1324{
1325 m_t << "\\item ";
1326 if (ref.isEmpty() && !fn.isEmpty())
1327 {
1328 m_t << "\\contentsline{section}{";
1329 }
1330}
1331
1333{
1334 if (ref.isEmpty() && !fn.isEmpty())
1335 {
1336 m_t << "}{\\pageref{" << stripPath(fn) << "}}{}\n";
1337 }
1338}
1339
1341 const QCString &path,const QCString &name)
1342{
1343 m_t << "\\item\\contentsline{section}\\textbf{ ";
1344 if (!path.isEmpty()) docify(path);
1345 docify(name);
1346 m_t << "} ";
1347}
1348
1350{
1351 m_t << "\\item\\contentsline{section}{";
1352}
1353
1357
1359{
1360 m_t << " ";
1361 if (hasBrief) m_t << "\\\\*";
1362}
1363
1364void LatexGenerator::endIndexValue(const QCString &name,bool /*hasBrief*/)
1365{
1366 //if (hasBrief) m_t << ")";
1367 m_t << "}{\\pageref{" << stripPath(name) << "}}{}\n";
1368}
1369
1370//void LatexGenerator::writeClassLink(const QCString &,const QCString &,
1371// const QCString &,const QCString &name)
1372//{
1373// m_t << "\\textbf{ ";
1374// docify(name);
1375// m_t << "}";
1376//}
1377
1379{
1380 bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
1381 if (!m_disableLinks && pdfHyperlinks)
1382 {
1383 m_t << "\\doxymbox{\\hyperlink{";
1384 if (!f.isEmpty()) m_t << stripPath(f);
1385 if (!anchor.isEmpty()) m_t << "_" << anchor;
1386 m_t << "}{";
1387 }
1388 else
1389 {
1390 m_t << "\\textbf{ ";
1391 }
1392}
1393
1395{
1396 bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
1397 if (!m_disableLinks && pdfHyperlinks)
1398 {
1399 m_t << "}";
1400 }
1401 m_t << "}";
1402}
1403
1404static QCString objectLinkToString(const QCString &ref, const QCString &f,
1405 const QCString &anchor, const QCString &text,
1406 bool insideTabbing,bool disableLinks)
1407{
1408 bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
1409 QCString result;
1410 if (!disableLinks && ref.isEmpty() && pdfHyperlinks)
1411 {
1412 result += "\\doxymbox{\\hyperlink{";
1413 if (!f.isEmpty()) result += stripPath(f);
1414 if (!f.isEmpty() && !anchor.isEmpty()) result += "_";
1415 if (!anchor.isEmpty()) result += anchor;
1416 result += "}{";
1417 result += convertToLaTeX(text,insideTabbing);
1418 result += "}}";
1419 }
1420 else
1421 {
1422 result += "\\textbf{ ";
1423 result += convertToLaTeX(text,insideTabbing);
1424 result += "}";
1425 }
1426 return result;
1427}
1428
1429static void processEntity(TextStream &t, bool pdfHyperlinks, const char *strForm, const char *strRepl)
1430{
1431 if (pdfHyperlinks)
1432 {
1433 t << "\\texorpdfstring{";
1434 }
1435 t << strForm;
1436 if (pdfHyperlinks)
1437 {
1438 t << "}{" << strRepl << "}";
1439 }
1440}
1441
1443 const QCString &anchor, const QCString &text)
1444{
1445 m_t << objectLinkToString(ref,f,anchor,text,m_codeGen->insideTabbing(),m_disableLinks);
1446}
1447
1449{
1450 m_t << " \\doxyref{}{";
1451}
1452
1453void LatexGenerator::endPageRef(const QCString &clname, const QCString &anchor)
1454{
1455 m_t << "}{";
1456 if (!clname.isEmpty()) m_t << clname;
1457 if (!anchor.isEmpty()) m_t << "_" << anchor;
1458 m_t << "}";
1459}
1460
1461
1463{
1464 int hierarchyLevel = m_hierarchyLevel;
1465 if (Config_getBool(COMPACT_LATEX))
1466 {
1467 ++hierarchyLevel;
1468 }
1469
1470 if (hierarchyLevel < 0)
1471 m_t << "\\chapter{";
1472 else
1473 m_t << "\\doxy" << QCString("sub").repeat(hierarchyLevel) << "section{";
1474}
1475
1477{
1478 m_t << "}\n";
1479
1480 bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
1481 bool usePDFLatex = Config_getBool(USE_PDFLATEX);
1482 if (usePDFLatex && pdfHyperlinks && !fileName.isEmpty())
1483 {
1484 m_t << "\\hypertarget{" << stripPath(fileName) << "}{}";
1485 }
1486
1488 if (!fn.isEmpty())
1489 {
1490 m_t << "\\label{" << fn << "}";
1491 }
1492 if (!name.isEmpty())
1493 {
1495 }
1496}
1497
1498void LatexGenerator::startGroupHeader(const QCString &,int extraIndentLevel)
1499{
1500 if (Config_getBool(COMPACT_LATEX))
1501 {
1502 extraIndentLevel++;
1503 }
1504
1505 if (extraIndentLevel>=3)
1506 {
1507 m_t << "\\doxysubparagraph*{";
1508 }
1509 else if (extraIndentLevel==2)
1510 {
1511 m_t << "\\doxyparagraph{";
1512 }
1513 else
1514 {
1515 extraIndentLevel += m_hierarchyLevel + 1;
1516 m_t << "\\doxy" << QCString("sub").repeat(extraIndentLevel) << "section{";
1517 }
1519}
1520
1522{
1524 m_t << "}\n";
1525}
1526
1528{
1529 int l = m_hierarchyLevel + 1;
1530 if (Config_getBool(COMPACT_LATEX))
1531 {
1532 ++l;
1533 }
1534
1535 m_t << "\\doxysub" << QCString("sub").repeat(l) << "section*{";
1537}
1538
1540{
1542 m_t << "}\n";
1543}
1544
1546 const QCString &memname,
1547 const QCString &,
1548 const QCString &title,
1549 int memCount,
1550 int memTotal,
1551 bool showInline)
1552{
1553 if (!memname.isEmpty() && memname[0]!='@')
1554 {
1555 latexWriteIndexItem(m_t,clname,memname);
1556 latexWriteIndexItem(m_t,memname,clname);
1557 }
1558 bool compactLatex = Config_getBool(COMPACT_LATEX);
1559 bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
1560 if (showInline)
1561 {
1562 m_t << "\\doxysubparagraph";
1563 }
1564 else if (compactLatex)
1565 {
1566 m_t << "\\doxyparagraph";
1567 }
1568 else
1569 {
1570 m_t << "\\doxy" << QCString("sub").repeat(m_hierarchyLevel + 2) << "section";
1571 }
1572
1573 m_t << "{";
1574 if (pdfHyperlinks)
1575 {
1576 m_t << "\\texorpdfstring{";
1577 }
1578 m_t << latexEscapeIndexChars(title);
1579 if (pdfHyperlinks)
1580 {
1581 m_t << "}{" << latexEscapePDFString(title) << "}";
1582 }
1583 if (memTotal>1)
1584 {
1585 m_t << "\\hspace{0.1cm}{\\footnotesize\\ttfamily [" << memCount << "/" << memTotal << "]}";
1586 }
1587 m_t << "}";
1588 m_t << "\n{\\footnotesize\\ttfamily ";
1589 //m_disableLinks=TRUE;
1590}
1591
1593{
1595 m_t << "}\n\n";
1596 //if (Config_getBool(COMPACT_LATEX)) m_t << "\\hfill";
1597}
1598
1600 const QCString &anchor, const QCString &,
1601 const QCString &)
1602{
1603 bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
1604 bool usePDFLatex = Config_getBool(USE_PDFLATEX);
1605 if (m_insideTableEnv) m_t << "\\doxymbox{"; // see issue #6093
1606 if (usePDFLatex && pdfHyperlinks)
1607 {
1608 m_t << "\\Hypertarget{";
1609 if (!fName.isEmpty()) m_t << stripPath(fName);
1610 if (!anchor.isEmpty()) m_t << "_" << anchor;
1611 m_t << "}";
1612 }
1613}
1614
1615void LatexGenerator::endDoxyAnchor(const QCString &/* fName */,const QCString &/* anchor */)
1616{
1617}
1618
1619void LatexGenerator::addLabel(const QCString &fName, const QCString &anchor)
1620{
1621 m_t << "\\label{";
1622 if (!fName.isEmpty()) m_t << stripPath(fName);
1623 if (!anchor.isEmpty()) m_t << "_" << anchor;
1624 if (m_insideTableEnv) m_t << "}";
1625 m_t << "} \n";
1626}
1627
1628void LatexGenerator::writeAnchor(const QCString &fName,const QCString &name)
1629{
1630 //printf("LatexGenerator::writeAnchor(%s,%s)\n",fName,name);
1631 m_t << "\\label{" << stripPath(name) << "}\n";
1632 bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
1633 bool usePDFLatex = Config_getBool(USE_PDFLATEX);
1634 if (usePDFLatex && pdfHyperlinks)
1635 {
1636 if (!fName.isEmpty())
1637 {
1638 m_t << "\\Hypertarget{" << stripPath(fName) << "_" << stripPath(name) << "}\n";
1639 }
1640 else
1641 {
1642 m_t << "\\Hypertarget{" << stripPath(name) << "}\n";
1643 }
1644 }
1645}
1646
1647
1648//void LatexGenerator::writeLatexLabel(const QCString &clName,const QCString &anchor)
1649//{
1650// writeDoxyAnchor(0,clName,anchor,0);
1651//}
1652
1654{
1655 if (!s1.isEmpty())
1656 {
1657 latexWriteIndexItem(m_t,s1,s2);
1658 }
1659}
1660
1661
1663{
1664 bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
1665 bool usePDFLatex = Config_getBool(USE_PDFLATEX);
1666 if (usePDFLatex && pdfHyperlinks)
1667 {
1668 m_t << "\\hypertarget{" << stripPath(lab) << "}{}";
1669 }
1670 m_t << "\\";
1671 if (Config_getBool(COMPACT_LATEX))
1672 {
1673 switch(type.level())
1674 {
1675 case SectionType::Page: m_t << "doxysubsection"; break;
1676 case SectionType::Section: m_t << "doxysubsubsection"; break;
1677 case SectionType::Subsection: m_t << "doxysubsubsubsection"; break;
1678 case SectionType::Subsubsection: m_t << "doxysubsubsubsubsection"; break;
1679 case SectionType::Paragraph: m_t << "doxysubsubsubsubsubsection"; break;
1680 case SectionType::Subparagraph: m_t << "doxysubsubsubsubsubsubsection"; break;
1681 case SectionType::Subsubparagraph: m_t << "doxysubsubsubsubsubsubsection"; break;
1682 default: ASSERT(0); break;
1683 }
1684 m_t << "{";
1685 }
1686 else
1687 {
1688 switch(type.level())
1689 {
1690 case SectionType::Page: m_t << "doxysection"; break;
1691 case SectionType::Section: m_t << "doxysubsection"; break;
1692 case SectionType::Subsection: m_t << "doxysubsubsection"; break;
1693 case SectionType::Subsubsection: m_t << "doxysubsubsubsection"; break;
1694 case SectionType::Paragraph: m_t << "doxysubsubsubsubsection"; break;
1695 case SectionType::Subparagraph: m_t << "doxysubsubsubsubsubsection"; break;
1696 case SectionType::Subsubparagraph: m_t << "doxysubsubsubsubsubsubsection"; break;
1697 default: ASSERT(0); break;
1698 }
1699 m_t << "{";
1700 }
1701}
1702
1704{
1705 m_t << "}\\label{" << lab << "}\n";
1706}
1707
1708
1710{
1712 m_codeGen->insideTabbing(), // insideTabbing
1713 false, // insidePre
1714 false, // insideItem
1715 m_codeGen->usedTableLevel()>0, // insideTable
1716 false // keepSpaces
1717 );
1718}
1719
1721{
1722 char cs[2];
1723 cs[0]=c;
1724 cs[1]=0;
1725 docify(cs);
1726}
1727
1729{
1730 //if (Config_getBool(COMPACT_LATEX)) m_t << "\\doxysubsubsection"; else m_t << "\\doxysubsection";
1731 //m_t << "{";
1732}
1733
1735 const QCString &fileName,const QCString &)
1736{
1738}
1739
1740
1742{
1743 if (indent==0)
1744 {
1745 m_t << "\\begin{tabbing}\n";
1746 m_t << "xx\\=xx\\=xx\\=xx\\=xx\\=xx\\=xx\\=xx\\=xx\\=\\kill\n";
1747 m_codeGen->setInsideTabbing(true);
1748 }
1749 m_indent=indent;
1750}
1751
1753{
1754 if (indent==0)
1755 {
1756 m_t << "\n" << "\\end{tabbing}";
1757 m_codeGen->setInsideTabbing(false);
1758 }
1759 m_indent=indent;
1760}
1761
1763{
1765 {
1766 m_t << "{\\footnotesize ";
1767 }
1768}
1769
1771{
1773 {
1774 m_t << "}\\\\";
1775 }
1776}
1777
1779{
1780 //printf("LatexGenerator::startMemberItem(%d)\n",annType);
1781 if (!m_codeGen->insideTabbing())
1782 {
1783 m_t << "\\item \n";
1785 }
1786}
1787
1789{
1790 if (m_codeGen->insideTabbing())
1791 {
1792 m_t << "\\\\";
1793 }
1795 m_t << "\n";
1796}
1797
1799{
1800 if (!m_codeGen->insideTabbing())
1801 {
1802 m_t << "\\begin{DoxyCompactList}\\small\\item\\em ";
1803 }
1804 else
1805 {
1806 for (int i=0;i<m_indent+2;i++) m_t << "\\>";
1807 m_t << "{\\em ";
1808 }
1809}
1810
1812{
1813 if (!m_codeGen->insideTabbing())
1814 {
1815 //m_t << "\\item\\end{DoxyCompactList}";
1816 m_t << "\\end{DoxyCompactList}";
1817 }
1818 else
1819 {
1820 m_t << "}\\\\\n";
1821 }
1822}
1823
1824
1826{
1827 //printf("writeNonBreakableSpace()\n");
1828 if (m_codeGen->insideTabbing())
1829 {
1830 m_t << "\\>";
1831 }
1832 else
1833 {
1834 m_t << "~";
1835 }
1836}
1837
1838// ----------------------------------------------
1839// nesting of functions below:
1840// startDescTable()
1841// - startDescTableRow()
1842// - startDescTableTitle()
1843// - endDescTableTitle()
1844// - startDescTableData()
1845// - endDescTableData()
1846// - endDescTableRow()
1847// - startDescTableRow()
1848// - ...
1849// - endDescTableRow()
1850// endDescTable()
1851
1852void LatexGenerator::startDescTable(const QCString &title,const bool hasInits)
1853{
1854 m_codeGen->incUsedTableLevel();
1855 m_t << "\\begin{DoxyEnumFields}[" << (hasInits?3:2) << "]{" << title << "}\n";
1856}
1857
1859{
1860 m_codeGen->decUsedTableLevel();
1861 m_t << "\\end{DoxyEnumFields}\n";
1862}
1863
1865{
1866 // this is needed to prevent the \hypertarget, \label, and \index commands from messing up
1867 // the row height (based on http://tex.stackexchange.com/a/186102)
1868 m_t << "\\raisebox{\\heightof{T}}[0pt][0pt]{";
1869}
1870
1874
1876{
1877 m_t << "}";
1878}
1879
1883
1885{
1886 m_t << "&";
1887}
1888
1892
1894{
1895 m_t << "&";
1896}
1897
1899{
1900 m_t << "\\\\\n\\hline\n\n";
1901}
1902
1906
1907
1909{
1910 if (!m_codeGen->insideTabbing())
1911 {
1912 m_t << "\\begin{DoxyCompactItemize}\n";
1913 }
1914}
1915
1917{
1918 //printf("LatexGenerator::endMemberList(%d)\n",m_codeGen->InsideTabbing());
1919 if (!m_codeGen->insideTabbing())
1920 {
1921 m_t << "\\end{DoxyCompactItemize}\n";
1922 }
1923}
1924
1925
1927{
1928 if (hasHeader)
1929 {
1930 m_t << "\\begin{Indent}";
1931 m_t << "\\textbf{ ";
1932 }
1933 // changed back to rev 756 due to bug 660501
1934 //if (Config_getBool(COMPACT_LATEX))
1935 //{
1936 // m_t << "\\doxysubparagraph*{";
1937 //}
1938 //else
1939 //{
1940 // m_t << "\\doxyparagraph*{";
1941 //}
1942}
1943
1945{
1946 // changed back to rev 756 due to bug 660501
1947 if (hasHeader) m_t << "}\\par\n";
1948 //m_t << "}\n";
1949}
1950
1952{
1953 m_t << "{\\em ";
1954}
1955
1957{
1958 m_t << "}";
1959}
1960
1964
1966{
1967 if (hasHeader)m_t << "\\end{Indent}";
1968 m_t << "\n";
1969}
1970
1972{
1973 m_t << "\n" << "\n";
1974}
1975
1980
1984
1989
1993
1998
2002
2007
2011
2016
2018{
2019 m_t << "\\begin{Desc}\n\\item[";
2020 docify(theTranslator->trExamples());
2021 m_t << "]";
2022}
2023
2025{
2026 m_t << "\\end{Desc}\n";
2027}
2028
2030{
2031 /* start of ParameterType ParameterName list */
2032 if (openBracket) m_t << "(";
2033 m_t << "\\begin{DoxyParamCaption}";
2034}
2035
2039
2041{
2042 m_t << "\\item[{";
2043 if (!first && !key.isEmpty()) docify(key);
2044}
2045
2047{
2048 m_t << "}]";
2049}
2050
2051void LatexGenerator::startParameterName(bool /*oneArgOnly*/)
2052{
2053 m_t << "{";
2054}
2055
2057{
2058 m_t << "}";
2059}
2060
2062{
2063 m_t << "{";
2064}
2065
2066void LatexGenerator::endParameterExtra(bool last,bool /*emptyList*/,bool closeBracket)
2067{
2068 m_t << "}";
2069 if (last)
2070 {
2071 m_t << "\\end{DoxyParamCaption}";
2072 if (closeBracket) m_t << ")";
2073 }
2074}
2075
2076void LatexGenerator::exceptionEntry(const QCString &prefix,bool closeBracket)
2077{
2078 if (!prefix.isEmpty())
2079 {
2080 m_t << " " << prefix << "(";
2081 }
2082 else if (closeBracket)
2083 {
2084 m_t << ")";
2085 }
2086 m_t << " ";
2087}
2088
2089void LatexGenerator::writeDoc(const IDocNodeAST *ast,const Definition *ctx,const MemberDef *,int,int)
2090{
2091 const DocNodeAST *astImpl = dynamic_cast<const DocNodeAST*>(ast);
2092 if (astImpl)
2093 {
2095 ctx?ctx->getDefFileExtension():QCString(""),
2097 std::visit(visitor,astImpl->root);
2098 }
2099}
2100
2102{
2103 m_t << "\\begin{Desc}\n\\item[";
2104 docify(header);
2105 m_t << "]";
2106 m_t << "\\begin{description}\n";
2107}
2108
2110{
2111 m_t << "\\item[{\\em ";
2112}
2113
2117
2119{
2120 m_t << "} : {\\em ";
2121}
2122
2124{
2125 m_t << "}]";
2126}
2127
2131
2135
2137{
2138 m_t << "\\end{description}\n";
2139 m_t << "\\end{Desc}\n";
2140}
2141
2143{
2144 if (Config_getBool(COMPACT_LATEX))
2145 {
2146 m_t << "\\doxyparagraph*{";
2147 }
2148 else
2149 {
2150 m_t << "\\doxy" << QCString("sub").repeat(m_hierarchyLevel + 1) << "section*{";
2151 }
2152}
2153
2155{
2156 m_t << "}\n";
2157}
2158
2160{
2161 if (m_codeGen->insideTabbing())
2162 {
2163 m_t << "\\\\\n";
2164 }
2165 else
2166 {
2167 m_t << "\\newline\n";
2168 }
2169}
2170
2172{
2173 m_codeGen->incUsedTableLevel();
2174 if (isEnum)
2175 {
2176 m_t << "\\begin{DoxyEnumFields}{";
2177 docify(theTranslator->trEnumerationValues());
2178 }
2179 else
2180 {
2181 m_t << "\\begin{DoxyFields}{";
2182 docify(theTranslator->trCompoundMembers());
2183 }
2184 m_t << "}\n";
2185 m_insideTableEnv=true;
2186}
2187
2189{
2190 m_insideTableEnv=false;
2191 m_codeGen->decUsedTableLevel();
2192 if (isEnum)
2193 {
2194 m_t << "\\end{DoxyEnumFields}\n";
2195 }
2196 else
2197 {
2198 m_t << "\\end{DoxyFields}\n";
2199 }
2200}
2201
2203{
2204 m_codeGen->setInsideTabbing(true); // to prevent \+ from causing unwanted breaks
2205}
2206
2208{
2209 m_t << "&\n";
2210 m_codeGen->setInsideTabbing(false);
2211}
2212
2214{
2215 m_codeGen->setInsideTabbing(true); // to prevent \+ from causing unwanted breaks
2216}
2217
2219{
2220 m_t << "&\n";
2221 m_codeGen->setInsideTabbing(false);
2222}
2223
2227
2229{
2230 m_t << "\\\\\n\\hline\n\n";
2231}
2232
2234{
2235 m_t << "\\hspace{0.3cm}";
2236}
2237
2238void LatexGenerator::writeLabel(const QCString &l,bool isLast)
2239{
2240 m_t << "{\\ttfamily [" << l << "]}";
2241 if (!isLast) m_t << ", ";
2242}
2243
2245{
2246}
2247
2249 const QCString &/*id*/,const QCString &ref,
2250 const QCString &file, const QCString &anchor,
2251 const QCString &title, const QCString &name)
2252{
2253 if (Config_getBool(COMPACT_LATEX))
2254 {
2255 m_t << "\\doxyparagraph*{";
2256 }
2257 else
2258 {
2259 m_t << "\\doxy" << QCString("sub").repeat(m_hierarchyLevel + 1) << "section*{";
2260 }
2261 m_t << theTranslator->trInheritedFrom(convertToLaTeX(title,m_codeGen->insideTabbing()),
2262 objectLinkToString(ref, file, anchor, name, m_codeGen->insideTabbing(), m_disableLinks));
2263 m_t << "}\n";
2264}
2265
2267{
2268 int maxLevel = level + m_hierarchyLevel;
2269 m_t << "\\etocsetnexttocdepth{" << maxLevel << "}\n";
2270 m_t << "\\localtableofcontents\n";
2271}
2272
2274{
2275 m_t << "\\begin{DoxyEmbeddedDoc}[" << indent << "]\n";
2276}
2277
2279{
2280 m_t << "\\end{DoxyEmbeddedDoc}\n";
2281}
2282
2283//--------------------------------------------------------------------------------------------------
2284
2286{
2287 // User-specified packages
2288 const StringVector &extraPackages = Config_getList(EXTRA_PACKAGES);
2289 if (!extraPackages.empty())
2290 {
2291 t << "% Packages requested by user\n";
2292 for (const auto &pkgName : extraPackages)
2293 {
2294 if ((pkgName[0] == '[') || (pkgName[0] == '{'))
2295 t << "\\usepackage" << pkgName << "\n";
2296 else
2297 t << "\\usepackage{" << pkgName << "}\n";
2298 }
2299 t << "\n";
2300 }
2301}
2302
2304{
2305 unsigned char minus[4]; // Superscript minus
2306 unsigned char sup2[3]; // Superscript two
2307 unsigned char sup3[3];
2308 minus[0]= 0xE2;
2309 minus[1]= 0x81;
2310 minus[2]= 0xBB;
2311 minus[3]= 0;
2312 sup2[0]= 0xC2;
2313 sup2[1]= 0xB2;
2314 sup2[2]= 0;
2315 sup3[0]= 0xC2;
2316 sup3[1]= 0xB3;
2317 sup3[2]= 0;
2318
2319 t << "\\ifPDFTeX\n";
2320 t << "\\usepackage{newunicodechar}\n";
2321 // taken from the newunicodechar package and removed the warning message
2322 // actually forcing to redefine the unicode character
2323 t << " \\makeatletter\n"
2324 " \\def\\doxynewunicodechar#1#2{%\n"
2325 " \\@tempswafalse\n"
2326 " \\edef\\nuc@tempa{\\detokenize{#1}}%\n"
2327 " \\if\\relax\\nuc@tempa\\relax\n"
2328 " \\nuc@emptyargerr\n"
2329 " \\else\n"
2330 " \\edef\\@tempb{\\expandafter\\@car\\nuc@tempa\\@nil}%\n"
2331 " \\nuc@check\n"
2332 " \\if@tempswa\n"
2333 " \\@namedef{u8:\\nuc@tempa}{#2}%\n"
2334 " \\fi\n"
2335 " \\fi\n"
2336 " }\n"
2337 " \\makeatother\n";
2338
2339 t << " \\doxynewunicodechar{" << minus << "}{${}^{-}$}% Superscript minus\n"
2340 " \\doxynewunicodechar{" << sup2 << "}{${}^{2}$}% Superscript two\n"
2341 " \\doxynewunicodechar{" << sup3 << "}{${}^{3}$}% Superscript three\n"
2342 "\n";
2343 t << "\\fi\n";
2344}
2345
2347 bool insideTabbing,bool insidePre,bool insideItem,bool insideTable,bool keepSpaces, const bool retainNewline)
2348{
2349 if (str.isEmpty()) return;
2350 bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
2351 //printf("filterLatexString(%s) insideTabbing=%d\n",qPrint(str),insideTabbing);
2352 const char *p = str.data();
2353 const char *q = nullptr;
2354 unsigned char pc='\0';
2355
2356 while (*p)
2357 {
2358 unsigned char c=static_cast<unsigned char>(*p++);
2359
2360 if (insidePre)
2361 {
2362 switch(c)
2363 {
2364 case 0xef: // handle U+FFFD i.e. "Replacement character" caused by octal: 357 277 275 / hexadecimal 0xef 0xbf 0xbd
2365 // the LaTeX command \ucr has been defined in doxygen.sty
2366 if (static_cast<unsigned char>(*(p)) == 0xbf && static_cast<unsigned char>(*(p+1)) == 0xbd)
2367 {
2368 t << "{\\ucr}";
2369 p += 2;
2370 }
2371 else
2372 t << static_cast<char>(c);
2373 break;
2374 case '\\': t << "\\(\\backslash\\)"; break;
2375 case '{': t << "\\{"; break;
2376 case '}': t << "\\}"; break;
2377 case '_': t << "\\_"; break;
2378 case '&': t << "\\&"; break;
2379 case '%': t << "\\%"; break;
2380 case '#': t << "\\#"; break;
2381 case '$': t << "\\$"; break;
2382 case '"': t << "\"{}"; break;
2383 case '-': t << "-\\/"; break;
2384 case '^': insideTable ? t << "\\string^" : t << static_cast<char>(c); break;
2385 case '~': t << "\\string~"; break;
2386 case '\n': if (retainNewline) t << "\\newline"; else t << ' ';
2387 break;
2388 case ' ': if (keepSpaces) t << "~"; else t << ' ';
2389 break;
2390 default:
2391 if (c<32) t << ' '; // non printable control character
2392 else t << static_cast<char>(c);
2393 break;
2394 }
2395 }
2396 else
2397 {
2398 switch(c)
2399 {
2400 case 0xef: // handle U+FFFD i.e. "Replacement character" caused by octal: 357 277 275 / hexadecimal 0xef 0xbf 0xbd
2401 // the LaTeX command \ucr has been defined in doxygen.sty
2402 if (static_cast<unsigned char>(*(p)) == 0xbf && static_cast<unsigned char>(*(p+1)) == 0xbd)
2403 {
2404 t << "{\\ucr}";
2405 p += 2;
2406 }
2407 else
2408 t << static_cast<char>(c);
2409 break;
2410 case '#': t << "\\+\\#"; break;
2411 case '$': t << "\\$"; break;
2412 case '%': t << "\\%"; break;
2413 case '^': processEntity(t,pdfHyperlinks,"$^\\wedge$","\\string^"); break;
2414 case '&': {
2415 // possibility to have a special symbol
2416 q = p;
2417 int cnt = 2; // we have to count & and ; as well
2418 while ((*q >= 'a' && *q <= 'z') || (*q >= 'A' && *q <= 'Z') || (*q >= '0' && *q <= '9'))
2419 {
2420 cnt++;
2421 q++;
2422 }
2423 if (*q == ';')
2424 {
2425 --p; // we need & as well
2428 {
2429 p++;
2430 t << "\\&";
2431 }
2432 else
2433 {
2435 q++;
2436 p = q;
2437 }
2438 }
2439 else
2440 {
2441 t << "\\&";
2442 }
2443 }
2444 break;
2445 case '*': processEntity(t,pdfHyperlinks,"$\\ast$","*"); break;
2446 case '_': if (!insideTabbing) t << "\\+";
2447 t << "\\_";
2448 if (!insideTabbing) t << "\\+";
2449 break;
2450 case '{': t << "\\{"; break;
2451 case '}': t << "\\}"; break;
2452 case '<': t << "$<$"; break;
2453 case '>': t << "$>$"; break;
2454 case '|': processEntity(t,pdfHyperlinks,"$\\vert$","|"); break;
2455 case '~': processEntity(t,pdfHyperlinks,"$\\sim$","\\string~"); break;
2456 case '[': if (Config_getBool(PDF_HYPERLINKS) || insideItem)
2457 t << "\\+[";
2458 else
2459 t << "[";
2460 break;
2461 case ']': if (pc=='[') t << "$\\,$";
2462 if (Config_getBool(PDF_HYPERLINKS) || insideItem)
2463 t << "]\\+";
2464 else
2465 t << "]";
2466 break;
2467 case '-': t << "-\\/";
2468 break;
2469 case '\\': t << "\\textbackslash{}";
2470 break;
2471 case '"': t << "\"{}";
2472 break;
2473 case '`': t << "\\`{}";
2474 break;
2475 case '\'': t << "\\textquotesingle{}";
2476 break;
2477 case '\n': if (retainNewline)
2478 {
2479 t << "\\newline";
2480 if (insideTable) t << " ";
2481 }
2482 else
2483 {
2484 t << ' ';
2485 }
2486 break;
2487 case ' ': if (keepSpaces) { if (insideTabbing) t << "\\>"; else t << '~'; } else t << ' ';
2488 break;
2489
2490 default:
2491 //if (!insideTabbing && forceBreaks && c!=' ' && *p!=' ')
2492 if (!insideTabbing &&
2493 ((c>='A' && c<='Z' && pc!=' ' && !(pc>='A' && pc <= 'Z') && pc!='\0' && *p) || (pc=='.' && isId(c)))
2494 )
2495 {
2496 t << "\\+";
2497 }
2498 if (c<32)
2499 {
2500 t << ' '; // non-printable control character
2501 }
2502 else
2503 {
2504 t << static_cast<char>(c);
2505 }
2506 if (!insideTabbing && ((c==':' && *p!=':') || c=='/'))
2507 {
2508 t << "\\+";
2509 }
2510 }
2511 }
2512 pc = c;
2513 }
2514}
2515
2516QCString convertToLaTeX(const QCString &s,bool insideTabbing,bool keepSpaces)
2517{
2518 TextStream t;
2519 filterLatexString(t,s,insideTabbing,false,false,false,keepSpaces);
2520 return t.str();
2521}
2522
2524{
2525 //printf("latexEscapeLabelName(%s)\n",qPrint(s));
2526 if (s.isEmpty()) return s;
2528 TextStream t;
2529 const char *p=s.data();
2530 char c = 0;
2531 while ((c=*p++))
2532 {
2533 switch (c)
2534 {
2535 case '|': t << "\\texttt{\"|}"; break;
2536 case '!': t << "\"!"; break;
2537 case '@': t << "\"@"; break;
2538 case '%': t << "\\%"; break;
2539 case '{': t << "\\lcurly{}"; break;
2540 case '}': t << "\\rcurly{}"; break;
2541 case '~': t << "````~"; break; // to get it a bit better in index together with other special characters
2542 // NOTE: adding a case here, means adding it to while below as well!
2543 default:
2544 {
2545 int i=0;
2546 // collect as long string as possible, before handing it to docify
2547 tmp[i++]=c;
2548 while ((c=*p) && c!='@' && c!='[' && c!=']' && c!='!' && c!='{' && c!='}' && c!='|')
2549 {
2550 tmp[i++]=c;
2551 p++;
2552 }
2553 tmp[i]=0;
2554 filterLatexString(t,tmp,
2555 true, // insideTabbing
2556 false, // insidePre
2557 false, // insideItem
2558 false, // insideTable
2559 false // keepSpaces
2560 );
2561 }
2562 break;
2563 }
2564 }
2565 return t.str();
2566}
2567
2569{
2570 //printf("latexEscapeIndexChars(%s)\n",qPrint(s));
2571 if (s.isEmpty()) return s;
2573 TextStream t;
2574 const char *p=s.data();
2575 char c = 0;
2576 while ((c=*p++))
2577 {
2578 switch (c)
2579 {
2580 case '!': t << "\"!"; break;
2581 case '"': t << "\"\""; break;
2582 case '@': t << "\"@"; break;
2583 case '|': t << "\\texttt{\"|}"; break;
2584 case '[': t << "["; break;
2585 case ']': t << "]"; break;
2586 case '{': t << "\\lcurly{}"; break;
2587 case '}': t << "\\rcurly{}"; break;
2588 // NOTE: adding a case here, means adding it to while below as well!
2589 default:
2590 {
2591 int i=0;
2592 // collect as long string as possible, before handing it to docify
2593 tmp[i++]=c;
2594 while ((c=*p) && c!='"' && c!='@' && c!='[' && c!=']' && c!='!' && c!='{' && c!='}' && c!='|')
2595 {
2596 tmp[i++]=c;
2597 p++;
2598 }
2599 tmp[i]=0;
2600 filterLatexString(t,tmp,
2601 true, // insideTabbing
2602 false, // insidePre
2603 false, // insideItem
2604 false, // insideTable
2605 false // keepSpaces
2606 );
2607 }
2608 break;
2609 }
2610 }
2611 return t.str();
2612}
2613
2615{
2616 if (s.isEmpty()) return s;
2617 TextStream t;
2618 const char *p=s.data();
2619 char c = 0;
2620 while ((c=*p++))
2621 {
2622 switch (c)
2623 {
2624 case '\\': t << "\\textbackslash{}"; break;
2625 case '{': t << "\\{"; break;
2626 case '}': t << "\\}"; break;
2627 case '_': t << "\\_"; break;
2628 case '%': t << "\\%"; break;
2629 case '&': t << "\\&"; break;
2630 case '#': t << "\\#"; break;
2631 case '$': t << "\\$"; break;
2632 case '^': t << "\\string^"; break;
2633 case '~': t << "\\string~"; break;
2634 default:
2635 t << c;
2636 break;
2637 }
2638 }
2639 return t.str();
2640}
2641
2643{
2644 constexpr auto hex = "0123456789ABCDEF";
2645 if (s.isEmpty()) return s;
2646 TextStream t;
2647 const char *p=s.data();
2648 char c = 0;
2649 while ((c=*p++))
2650 {
2651 switch (c)
2652 {
2653 case '#': t << "\\#"; break;
2654 case '%': t << "\\%"; break;
2655 case '\\': t << "\\\\"; break;
2656 case '\n': break; // ignore
2657 default:
2658 if (c<0)
2659 {
2660 unsigned char id = static_cast<unsigned char>(c);
2661 t << "\\%" << hex[id>>4] << hex[id&0xF];
2662 }
2663 else
2664 {
2665 t << c;
2666 }
2667 break;
2668 }
2669 }
2670 return t.str();
2671}
2672
2673void latexWriteIndexItem(TextStream &m_t,const QCString &s1,const QCString &s2)
2674{
2675 if (!s1.isEmpty())
2676 {
2677 m_t << "\\index{";
2678 m_t << latexEscapeLabelName(s1);
2679 m_t << "@{";
2680 m_t << latexEscapeIndexChars(s1);
2681 m_t << "}";
2682 if (!s2.isEmpty())
2683 {
2684 m_t << "!";
2685 m_t << latexEscapeLabelName(s2);
2686 m_t << "@{";
2687 m_t << latexEscapeIndexChars(s2);
2688 m_t << "}";
2689 }
2690 m_t << "}\n";
2691 }
2692}
2693
2694
constexpr auto prefix
Definition anchor.cpp:44
QCString latexBibFiles()
lists the bibtex cite files in a comma separated list
Definition cite.cpp:575
static CitationManager & instance()
Definition cite.cpp:85
bool isEmpty() const
return TRUE if there are no citations.
Definition cite.cpp:115
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:1065
The common base class of all entity definitions found in the sources.
Definition definition.h:77
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:1463
DocNodeVariant root
Definition docnode.h:1488
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:114
static ConceptLinkedMap * conceptLinkedMap
Definition doxygen.h:97
static std::unique_ptr< PageDef > mainPage
Definition doxygen.h:100
static FileNameLinkedMap * inputNameLinkedMap
Definition doxygen.h:104
static ClassLinkedMap * classLinkedMap
Definition doxygen.h:95
static PageLinkedMap * exampleLinkedMap
Definition doxygen.h:98
static PageLinkedMap * pageLinkedMap
Definition doxygen.h:99
static DirLinkedMap * dirLinkedMap
Definition doxygen.h:126
static GroupLinkedMap * groupLinkedMap
Definition doxygen.h:113
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:190
void endFontClass() override
Definition latexgen.cpp:296
void writeLineNumber(const QCString &, const QCString &, const QCString &, int, bool) override
Definition latexgen.cpp:221
void setSourceFileName(const QCString &sourceFileName)
Definition latexgen.cpp:72
void setRelativePath(const QCString &path)
Definition latexgen.cpp:67
void startFontClass(const QCString &) override
Definition latexgen.cpp:290
void endSpecialComment() override
Definition latexgen.cpp:185
void stripCodeComments(bool b) override
Definition latexgen.cpp:175
void startCodeFragment(const QCString &style) override
Definition latexgen.cpp:302
size_t m_stripIndentAmount
Definition latexgen.h:89
void startCodeLine(int) override
Definition latexgen.cpp:268
LatexCodeGenerator(TextStream *t, const QCString &relPath, const QCString &sourceFile)
Definition latexgen.cpp:58
void startSpecialComment() override
Definition latexgen.cpp:180
void endCodeFragment(const QCString &style) override
Definition latexgen.cpp:307
QCString m_sourceFileName
Definition latexgen.h:82
void codify(const QCString &text) override
Definition latexgen.cpp:77
void endCodeLine() override
Definition latexgen.cpp:279
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:195
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:361
void endIndexKey() override
void endInlineMemberDoc() override
void startProjectNumber() override
Definition latexgen.cpp:733
void cleanup() override
Definition latexgen.cpp:678
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:328
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 startFile(const QCString &name, bool isSource, const QCString &manName, const QCString &title, int id, int hierarchyLevel) override
Definition latexgen.cpp:708
void docify(const QCString &text) override
void startAnonTypeScope(int) override
void endPlainFile() override
Definition latexgen.h:317
void startDoxyAnchor(const QCString &, const QCString &, const QCString &, const QCString &, const QCString &) override
static void writeFooterFile(TextStream &t)
Definition latexgen.cpp:696
void startParameterList(bool) override
void endMemberDoc(bool) override
void endConstraintType() override
void startDescTableRow() override
void endAnonTypeScope(int) override
QCString m_relPath
Definition latexgen.h:325
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
void endMemberGroupHeader(bool) override
static void writeStyleSheetFile(TextStream &t)
Definition latexgen.cpp:702
void endTitleHead(const QCString &, const QCString &name) override
void endMemberHeader() override
OutputType type() const override
Definition latexgen.h:111
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 startConstraintParam() override
void lineBreak(const QCString &style=QCString()) override
void endInlineMemberName() override
void startMemberTemplateParams() override
void startInlineMemberType() override
int m_hierarchyLevel
Definition latexgen.h:331
void startInlineMemberDoc() override
void writeAnchor(const QCString &fileName, const QCString &name) override
void startCallGraph() override
void endMemberList() override
void startEmbeddedDoc(int) override
void endFile() override
Definition latexgen.cpp:722
void startExamples() override
LatexGenerator & operator=(const LatexGenerator &)
Definition latexgen.cpp:341
void startDirDepGraph() override
void endTextLink() override
void endEmbeddedDoc() 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:316
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:324
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:329
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:323
static void writeHeaderFile(TextStream &t)
Definition latexgen.cpp:690
void endParagraph() override
void addLabel(const QCString &, const QCString &) override
bool m_insideTableEnv
Definition latexgen.h:330
void writeStyleInfo(int part) override
void endDoxyAnchor(const QCString &, const QCString &) override
void startIndexValue(bool) override
void startInlineMemberName() override
void writeDoc(const IDocNodeAST *node, const Definition *ctx, const MemberDef *, int id, int sectionLevel) override
static void init()
Definition latexgen.cpp:632
bool m_templateMemberItem
Definition latexgen.h:327
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:165
void add(OutputCodeIntfPtr &&p)
Definition outputlist.h:195
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:422
size_t length() const
Returns the length of the string, not counting the 0-terminator.
Definition qcstring.h:166
bool isEmpty() const
Returns TRUE iff the string is empty.
Definition qcstring.h:163
QCString repeat(unsigned int n) const
Definition qcstring.h:321
const std::string & str() const
Definition qcstring.h:552
QCString & sprintf(const char *format,...)
Definition qcstring.cpp:29
@ ExplicitSize
Definition qcstring.h:146
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:172
QCString quoted() const
Definition qcstring.h:275
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:216
#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:62
QCString yearToString()
Returns the current year as a string.
Definition datetime.cpp:75
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:63
static QCString g_header_file
Definition htmlgen.cpp:64
static QCString g_footer
Definition htmlgen.cpp:66
static QCString g_footer_file
Definition htmlgen.cpp:65
static void writeDefaultStyleSheet(TextStream &t)
Definition htmlgen.cpp:1411
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:366
static const SelectionMarkerInfo latexMarkerInfo
Definition latexgen.cpp:54
static QCString extraLatexStyleSheet()
Definition latexgen.cpp:738
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:502
static void writeDefaultStyleSheet(TextStream &t)
Definition latexgen.cpp:685
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 latexWriteIndexItem(TextStream &m_t, const QCString &s1, const QCString &s2)
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)
void latexWriteIndexItem(TextStream &t, const QCString &r1, const QCString &s2="")
QCString latexEscapeIndexChars(const QCString &s)
#define term(fmt,...)
Definition message.h:137
std::ofstream openOutputStream(const QCString &name, bool append=false)
Definition portable.cpp:648
const char * ghostScriptCommand()
Definition portable.cpp:437
OutputCodeDefer< LatexCodeGenerator > LatexCodeGeneratorDefer
Definition outputlist.h:103
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:571
#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:6903
void checkBlocks(const QCString &s, const QCString fileName, const SelectionMarkerInfo &markerInfo)
Definition util.cpp:6545
QCString stripPath(const QCString &s)
Definition util.cpp:4952
QCString removeEmptyLines(const QCString &s)
Definition util.cpp:6609
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:6432
QCString substituteKeywords(const QCString &file, const QCString &s, const KeywordSubstitutionList &keywords)
Definition util.cpp:3058
QCString relativePathToRoot(const QCString &name)
Definition util.cpp:3583
void clearSubDirs(const Dir &d)
Definition util.cpp:3671
QCString fileToString(const QCString &name, bool filter, bool isSourceCode)
Definition util.cpp:1494
QCString stripExtensionGeneral(const QCString &fName, const QCString &ext)
Definition util.cpp:4937
void createSubDirs(const Dir &d)
Definition util.cpp:3644
bool checkExtension(const QCString &fName, const QCString &ext)
Definition util.cpp:4920
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:5880
A bunch of utility functions.
bool isId(int c)
Definition util.h:256