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
53static const SelectionMarkerInfo latexMarkerInfo = { '%', "%%BEGIN ",8 ,"%%END ",6, "",0 };
54
55static QCString substituteLatexKeywords(const QCString &str, const QCString &title);
56
58 : m_t(t), m_relPath(relPath), m_sourceFileName(sourceFileName)
59{
60}
61
65
67{
68 m_relPath = path;
69}
70
75
77{
78 if (!str.isEmpty())
79 {
80 const char *p=str.data();
81 char c = 0;
82 //char cs[5];
83 int tabSize = Config_getInt(TAB_SIZE);
84 static THREAD_LOCAL char *result = nullptr;
85 static THREAD_LOCAL int lresult = 0;
86 if (m_hide) // only update column count
87 {
89 }
90 else // actually output content and keep track of m_col
91 {
92 while ((c=*p))
93 {
94 switch(c)
95 {
96 case 0x0c: p++; // remove ^L
97 break;
98 case ' ': if (m_col>=m_stripIndentAmount)
99 {
100 *m_t << (m_doxyCodeLineOpen ? "\\ " : " ");
101 }
102 m_col++;
103 p++;
104 break;
105 case '^': *m_t <<"\\string^";
106 m_col++;
107 p++;
108 break;
109 case '`': *m_t <<"\\`{}";
110 m_col++;
111 p++;
112 break;
113 case '\t': {
114 int spacesToNextTabStop = tabSize - (m_col%tabSize);
115 while (spacesToNextTabStop--)
116 {
118 {
119 *m_t << (m_doxyCodeLineOpen ? "\\ " : " ");
120 }
121 m_col++;
122 }
123 p++;
124 }
125 break;
126 case '\n': *m_t << '\n';
127 m_col=0;
128 p++;
129 break;
130 default:
131 {
132 int i=0;
133
134#undef COPYCHAR
135// helper macro to copy a single utf8 character, dealing with multibyte chars.
136#define COPYCHAR() do { \
137 int bytes = getUTF8CharNumBytes(c); \
138 if (lresult < (i + bytes + 1)) \
139 { \
140 lresult += 512; \
141 result = static_cast<char *>(realloc(result, lresult)); \
142 } \
143 for (int j=0; j<bytes && *p; j++) \
144 { \
145 result[i++]=*p++; \
146 } \
147 m_col++; \
148 } while(0)
149
150 // gather characters until we find whitespace or another special character
151 COPYCHAR();
152 while ((c=*p) &&
153 c!=0x0c && c!='\t' && c!='\n' && c!=' ' && c!='^'
154 )
155 {
156 COPYCHAR();
157 }
158 result[i]=0; // add terminator
159 filterLatexString(*m_t,result,
160 m_insideTabbing, // insideTabbing
161 true, // insidePre
162 false, // insideItem
163 m_usedTableLevel>0, // insideTable
164 false // keepSpaces
165 );
166 }
167 break;
168 }
169 }
170 }
171 }
172}
173
178
183
185{
186 m_hide = false;
187}
188
190{
191 m_stripIndentAmount = amount;
192}
193
195 const QCString &ref,const QCString &f,
196 const QCString &anchor,const QCString &name,
197 const QCString &)
198{
199 if (m_hide) return;
200 bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
201 bool usePDFLatex = Config_getBool(USE_PDFLATEX);
202 size_t l = name.length();
203 if (ref.isEmpty() && usePDFLatex && pdfHyperlinks)
204 {
205 *m_t << "\\mbox{\\hyperlink{";
206 if (!f.isEmpty()) *m_t << stripPath(f);
207 if (!f.isEmpty() && !anchor.isEmpty()) *m_t << "_";
208 if (!anchor.isEmpty()) *m_t << anchor;
209 *m_t << "}{";
210 codify(name);
211 *m_t << "}}";
212 }
213 else
214 {
215 codify(name);
216 }
217 m_col+=l;
218}
219
220void LatexCodeGenerator::writeLineNumber(const QCString &ref,const QCString &fileName,const QCString &anchor,int l,bool writeLineAnchor)
221{
222 if (m_hide) return;
223 bool usePDFLatex = Config_getBool(USE_PDFLATEX);
224 bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
226 {
227 *m_t << "\\DoxyCodeLine{";
229 }
230 if (Config_getBool(SOURCE_BROWSER))
231 {
232 QCString lineNumber;
233 lineNumber.sprintf("%05d",l);
234
235 QCString lineAnchor;
236 if (!m_sourceFileName.isEmpty())
237 {
238 lineAnchor.sprintf("_l%05d",l);
240 }
241 bool showTarget = usePDFLatex && pdfHyperlinks && !lineAnchor.isEmpty() && writeLineAnchor;
242 if (showTarget)
243 {
244 *m_t << "\\Hypertarget{" << stripPath(lineAnchor) << "}";
245 }
246 if (!fileName.isEmpty())
247 {
248 writeCodeLink(CodeSymbolType::Default,ref,fileName,anchor,lineNumber,QCString());
249 }
250 else
251 {
252 codify(lineNumber);
253 }
254 *m_t << "\\ ";
255 }
256 else
257 {
258 QCString lineNumber;
259 lineNumber.sprintf("%05d",l);
260 codify(lineNumber);
261 *m_t << "\\ ";
262 }
263 m_col=0;
264}
265
266
268{
269 if (m_hide) return;
270 m_col=0;
272 {
273 *m_t << "\\DoxyCodeLine{";
275 }
276}
277
279{
280 if (m_hide) return;
282 {
283 *m_t << "}";
285 }
286 codify("\n");
287}
288
290{
291 if (m_hide) return;
292 *m_t << "\\textcolor{" << name << "}{";
293}
294
296{
297 if (m_hide) return;
298 *m_t << "}";
299}
300
302{
303 *m_t << "\n\\begin{" << style << "}{" << m_usedTableLevel << "}\n";
304}
305
307{
308 //endCodeLine checks is there is still an open code line, if so closes it.
309 endCodeLine();
310
311 *m_t << "\\end{" << style << "}\n";
312}
313
314
315//-------------------------------
316
318 : OutputGenerator(Config_getString(LATEX_OUTPUT))
319 , m_codeList(std::make_unique<OutputCodeList>())
320{
321 m_codeGen = m_codeList->add<LatexCodeGenerator>(&m_t);
322}
323
325{
326 m_codeList = std::make_unique<OutputCodeList>(*og.m_codeList);
327 m_codeGen = m_codeList->get<LatexCodeGenerator>(OutputType::Latex);
328 m_codeGen->setTextStream(&m_t);
331 m_relPath = og.m_relPath;
332 m_indent = og.m_indent;
335}
336
338{
339 if (this!=&og)
340 {
341 m_dir = og.m_dir;
342 m_codeList = std::make_unique<OutputCodeList>(*og.m_codeList);
343 m_codeGen = m_codeList->get<LatexCodeGenerator>(OutputType::Latex);
344 m_codeGen->setTextStream(&m_t);
347 m_relPath = og.m_relPath;
348 m_indent = og.m_indent;
351 }
352 return *this;
353}
354
356
361
363{
364 bool generateBib = !CitationManager::instance().isEmpty();
365 QCString fileName=Config_getString(LATEX_OUTPUT)+"/Makefile";
366 std::ofstream f = Portable::openOutputStream(fileName);
367 if (!f.is_open())
368 {
369 term("Could not open file %s for writing\n",qPrint(fileName));
370 }
371 TextStream t(&f);
372 // inserted by KONNO Akihisa <konno@researchers.jp> 2002-03-05
373 QCString latex_command = theTranslator->latexCommandName().quoted();
374 QCString mkidx_command = Config_getString(MAKEINDEX_CMD_NAME).quoted();
375 QCString bibtex_command = "bibtex";
376 QCString manual_file = "refman";
377 const int latex_count = 8;
378 // end insertion by KONNO Akihisa <konno@researchers.jp> 2002-03-05
379 t << "LATEX_CMD?=" << latex_command << "\n"
380 << "MKIDX_CMD?=" << mkidx_command << "\n"
381 << "BIBTEX_CMD?=" << bibtex_command << "\n"
382 << "LATEX_COUNT?=" << latex_count << "\n"
383 << "MANUAL_FILE?=" << manual_file << "\n"
384 << "\n";
385 if (!Config_getBool(USE_PDFLATEX)) // use plain old latex
386 {
387 t << "all: $(MANUAL_FILE).dvi\n"
388 << "\n"
389 << "ps: $(MANUAL_FILE).ps\n"
390 << "\n"
391 << "pdf: $(MANUAL_FILE).pdf\n"
392 << "\n"
393 << "ps_2on1: $(MANUAL_FILE).ps\n"
394 << "\n"
395 << "pdf_2on1: $(MANUAL_FILE).pdf\n"
396 << "\n"
397 << "$(MANUAL_FILE).ps: $(MANUAL_FILE).dvi\n"
398 << "\tdvips -o $(MANUAL_FILE).ps $(MANUAL_FILE).dvi\n"
399 << "\n";
400 t << "$(MANUAL_FILE).pdf: $(MANUAL_FILE).ps\n";
401 t << "\tps2pdf $(MANUAL_FILE).ps $(MANUAL_FILE).pdf\n\n";
402 t << "$(MANUAL_FILE).dvi: clean $(MANUAL_FILE).tex doxygen.sty\n"
403 << "\techo \"Running latex...\"\n"
404 << "\t$(LATEX_CMD) $(MANUAL_FILE).tex || \\\n"
405 << "\tif [ $$? != 0 ] ; then \\\n"
406 << "\t \\echo \"Please consult $(MANUAL_FILE).log to see the error messages\" ; \\\n"
407 << "\t false; \\\n"
408 << "\tfi\n"
409 << "\techo \"Running makeindex...\"\n"
410 << "\t$(MKIDX_CMD) $(MANUAL_FILE).idx\n";
411 if (generateBib)
412 {
413 t << "\techo \"Running bibtex...\"\n";
414 t << "\t$(BIBTEX_CMD) $(MANUAL_FILE)\n";
415 t << "\techo \"Rerunning latex....\"\n";
416 t << "\t$(LATEX_CMD) $(MANUAL_FILE).tex || \\\n"
417 << "\tif [ $$? != 0 ] ; then \\\n"
418 << "\t \\echo \"Please consult $(MANUAL_FILE).log to see the error messages\" ; \\\n"
419 << "\t false; \\\n"
420 << "\tfi\n";
421 }
422 t << "\techo \"Rerunning latex....\"\n"
423 << "\t$(LATEX_CMD) $(MANUAL_FILE).tex\n"
424 << "\tlatex_count=$(LATEX_COUNT) ; \\\n"
425 << "\twhile grep -E -s 'Rerun (LaTeX|to get cross-references right|to get bibliographical references right)' $(MANUAL_FILE).log && [ $$latex_count -gt 0 ] ;\\\n"
426 << "\t do \\\n"
427 << "\t echo \"Rerunning latex....\" ;\\\n"
428 << "\t $(LATEX_CMD) $(MANUAL_FILE).tex ; \\\n"
429 << "\t $(LATEX_CMD) $(MANUAL_FILE).tex || \\\n"
430 << "\t if [ $$? != 0 ] ; then \\\n"
431 << "\t \\echo \"Please consult $(MANUAL_FILE).log to see the error messages\" ; \\\n"
432 << "\t false; \\\n"
433 << "\t fi; \\\n"
434 << "\t latex_count=`expr $$latex_count - 1` ;\\\n"
435 << "\t done\n"
436 << "\t$(MKIDX_CMD) $(MANUAL_FILE).idx\n"
437 << "\t$(LATEX_CMD) $(MANUAL_FILE).tex || \\\n"
438 << "\tif [ $$? != 0 ] ; then \\\n"
439 << "\t \\echo \"Please consult $(MANUAL_FILE).log to see the error messages\" ; \\\n"
440 << "\t false; \\\n"
441 << "\tfi\n"
442 << "$(MANUAL_FILE).ps: $(MANUAL_FILE).ps\n"
443 << "\tpsnup -2 $(MANUAL_FILE).ps >$(MANUAL_FILE).ps\n"
444 << "\n"
445 << "$(MANUAL_FILE).pdf: $(MANUAL_FILE).ps\n"
446 << "\tps2pdf $(MANUAL_FILE).ps $(MANUAL_FILE).pdf\n";
447 }
448 else // use pdflatex for higher quality output
449 {
450 t << "all: $(MANUAL_FILE).pdf\n\n"
451 << "pdf: $(MANUAL_FILE).pdf\n\n";
452 t << "$(MANUAL_FILE).pdf: clean $(MANUAL_FILE).tex\n";
453 t << "\t$(LATEX_CMD) $(MANUAL_FILE) || \\\n"
454 << "\tif [ $$? != 0 ] ; then \\\n"
455 << "\t \\echo \"Please consult $(MANUAL_FILE).log to see the error messages\" ; \\\n"
456 << "\t false; \\\n"
457 << "\tfi\n";
458 t << "\t$(MKIDX_CMD) $(MANUAL_FILE).idx\n";
459 if (generateBib)
460 {
461 t << "\t$(BIBTEX_CMD) $(MANUAL_FILE)\n";
462 t << "\t$(LATEX_CMD) $(MANUAL_FILE) || \\\n"
463 << "\tif [ $$? != 0 ] ; then \\\n"
464 << "\t \\echo \"Please consult $(MANUAL_FILE).log to see the error messages\" ; \\\n"
465 << "\t false; \\\n"
466 << "\tfi\n";
467 }
468 t << "\t$(LATEX_CMD) $(MANUAL_FILE) || \\\n"
469 << "\tif [ $$? != 0 ] ; then \\\n"
470 << "\t \\echo \"Please consult $(MANUAL_FILE).log to see the error messages\" ; \\\n"
471 << "\t false; \\\n"
472 << "\tfi\n"
473 << "\tlatex_count=$(LATEX_COUNT) ; \\\n"
474 << "\twhile grep -E -s 'Rerun (LaTeX|to get cross-references right|to get bibliographical references right)' $(MANUAL_FILE).log && [ $$latex_count -gt 0 ] ;\\\n"
475 << "\t do \\\n"
476 << "\t echo \"Rerunning latex....\" ;\\\n"
477 << "\t $(LATEX_CMD) $(MANUAL_FILE) || \\\n"
478 << "\t if [ $$? != 0 ] ; then \\\n"
479 << "\t \\echo \"Please consult $(MANUAL_FILE).log to see the error messages\" ; \\\n"
480 << "\t false; \\\n"
481 << "\t fi; \\\n"
482 << "\t latex_count=`expr $$latex_count - 1` ;\\\n"
483 << "\t done\n"
484 << "\t$(MKIDX_CMD) $(MANUAL_FILE).idx\n"
485 << "\t$(LATEX_CMD) $(MANUAL_FILE) || \\\n"
486 << "\tif [ $$? != 0 ] ; then \\\n"
487 << "\t \\echo \"Please consult $(MANUAL_FILE).log to see the error messages\" ; \\\n"
488 << "\t false; \\\n"
489 << "\tfi\n";
490 }
491
492 t << "\n"
493 << "clean:\n"
494 << "\trm -f "
495 << "*.ps *.dvi *.aux *.toc *.idx *.ind *.ilg *.log *.out *.brf *.blg *.bbl $(MANUAL_FILE).pdf\n";
496}
497
498static void writeMakeBat()
499{
500#if defined(_MSC_VER)
501 QCString dir=Config_getString(LATEX_OUTPUT);
502 QCString fileName=dir+"/make.bat";
503 QCString latex_command = theTranslator->latexCommandName().quoted();
504 QCString mkidx_command = Config_getString(MAKEINDEX_CMD_NAME).quoted();
505 QCString bibtex_command = "bibtex";
506 QCString manual_file = "refman";
507 const int latex_count = 8;
508 bool generateBib = !CitationManager::instance().isEmpty();
509 std::ofstream t = Portable::openOutputStream(fileName);
510 if (!t.is_open())
511 {
512 term("Could not open file %s for writing\n",qPrint(fileName));
513 }
514 t << "pushd %~dp0\r\n";
515 t << "if not %errorlevel% == 0 goto :end1\r\n";
516 t << "\r\n";
517 t << "set ORG_LATEX_CMD=%LATEX_CMD%\r\n";
518 t << "set ORG_MKIDX_CMD=%MKIDX_CMD%\r\n";
519 t << "set ORG_BIBTEX_CMD=%BIBTEX_CMD%\r\n";
520 t << "set ORG_LATEX_COUNT=%LATEX_COUNT%\r\n";
521 t << "set ORG_MANUAL_FILE=%MANUAL_FILE%\r\n";
522 t << "if \"X\"%LATEX_CMD% == \"X\" set LATEX_CMD=" << latex_command << "\r\n";
523 t << "if \"X\"%MKIDX_CMD% == \"X\" set MKIDX_CMD=" << mkidx_command << "\r\n";
524 t << "if \"X\"%BIBTEX_CMD% == \"X\" set BIBTEX_CMD=" << bibtex_command << "\r\n";
525 t << "if \"X\"%LATEX_COUNT% == \"X\" set LATEX_COUNT=" << latex_count << "\r\n";
526 t << "if \"X\"%MANUAL_FILE% == \"X\" set MANUAL_FILE=" << manual_file << "\r\n";
527 t << "\r\n";
528 t << "del /s /f *.ps *.dvi *.aux *.toc *.idx *.ind *.ilg *.log *.out *.brf *.blg *.bbl %MANUAL_FILE%.pdf\r\n\r\n";
529 t << "\r\n";
530 if (!Config_getBool(USE_PDFLATEX)) // use plain old latex
531 {
532 t << "%LATEX_CMD% %MANUAL_FILE%.tex\r\n";
533 t << "@if ERRORLEVEL 1 goto :error\r\n";
534 t << "echo ----\r\n";
535 t << "%MKIDX_CMD% %MANUAL_FILE%.idx\r\n";
536 if (generateBib)
537 {
538 t << "%BIBTEX_CMD% %MANUAL_FILE%\r\n";
539 t << "echo ----\r\n";
540 t << "\t%LATEX_CMD% %MANUAL_FILE%.tex\r\n";
541 t << "@if ERRORLEVEL 1 goto :error\r\n";
542 }
543 t << "setlocal enabledelayedexpansion\r\n";
544 t << "set count=%LAT#EX_COUNT%\r\n";
545 t << ":repeat\r\n";
546 t << "set content=X\r\n";
547 t << "for /F \"tokens=*\" %%T in ( 'findstr /C:\"Rerun LaTeX\" %MANUAL_FILE%.log' ) do set content=\"%%~T\"\r\n";
548 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";
549 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";
550 t << "if !content! == X goto :skip\r\n";
551 t << "set /a count-=1\r\n";
552 t << "if !count! EQU 0 goto :skip\r\n\r\n";
553 t << "echo ----\r\n";
554 t << "%LATEX_CMD% %MANUAL_FILE%.tex\r\n";
555 t << "@if ERRORLEVEL 1 goto :error\r\n";
556 t << "goto :repeat\r\n";
557 t << ":skip\r\n";
558 t << "endlocal\r\n";
559 t << "%MKIDX_CMD% %MANUAL_FILE%.idx\r\n";
560 t << "%LATEX_CMD% %MANUAL_FILE%.tex\r\n";
561 t << "@if ERRORLEVEL 1 goto :error\r\n";
562 t << "dvips -o %MANUAL_FILE%.ps %MANUAL_FILE%.dvi\r\n";
564 t << " -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite "
565 "-sOutputFile=%MANUAL_FILE%.pdf -c save pop -f %MANUAL_FILE%.ps\r\n";
566 }
567 else // use pdflatex
568 {
569 t << "%LATEX_CMD% %MANUAL_FILE%\r\n";
570 t << "@if ERRORLEVEL 1 goto :error\r\n";
571 t << "echo ----\r\n";
572 t << "%MKIDX_CMD% %MANUAL_FILE%.idx\r\n";
573 if (generateBib)
574 {
575 t << "%BIBTEX_CMD% %MANUAL_FILE%\r\n";
576 t << "%LATEX_CMD% %MANUAL_FILE%\r\n";
577 t << "@if ERRORLEVEL 1 goto :error\r\n";
578 }
579 t << "echo ----\r\n";
580 t << "%LATEX_CMD% %MANUAL_FILE%\r\n";
581 t << "@if ERRORLEVEL 1 goto :error\r\n";
582 t << "\r\n";
583 t << "setlocal enabledelayedexpansion\r\n";
584 t << "set count=%LATEX_COUNT%\r\n";
585 t << ":repeat\r\n";
586 t << "set content=X\r\n";
587 t << "for /F \"tokens=*\" %%T in ( 'findstr /C:\"Rerun LaTeX\" %MANUAL_FILE%.log' ) do set content=\"%%~T\"\r\n";
588 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";
589 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";
590 t << "if !content! == X goto :skip\r\n";
591 t << "set /a count-=1\r\n";
592 t << "if !count! EQU 0 goto :skip\r\n\r\n";
593 t << "echo ----\r\n";
594 t << "%LATEX_CMD% %MANUAL_FILE%\r\n";
595 t << "@if ERRORLEVEL 1 goto :error\r\n";
596 t << "goto :repeat\r\n";
597 t << ":skip\r\n";
598 t << "endlocal\r\n";
599 t << "%MKIDX_CMD% %MANUAL_FILE%.idx\r\n";
600 t << "%LATEX_CMD% %MANUAL_FILE%\r\n";
601 t << "@if ERRORLEVEL 1 goto :error\r\n";
602 }
603 t<< "\r\n";
604 t << "goto :end\r\n";
605 t << ":error\r\n";
606 t << "@echo ===============\r\n";
607 t << "@echo Please consult %MANUAL_FILE%.log to see the error messages\r\n";
608 t << "@echo ===============\r\n";
609 t<< "\r\n";
610 t<< ":end\r\n";
611 t<< "@REM reset environment\r\n";
612 t<< "popd\r\n";
613 t<< "set LATEX_CMD=%ORG_LATEX_CMD%\r\n";
614 t<< "set ORG_LATEX_CMD=\r\n";
615 t<< "set MKIDX_CMD=%ORG_MKIDX_CMD%\r\n";
616 t<< "set ORG_MKIDX_CMD=\r\n";
617 t<< "set BIBTEX_CMD=%ORG_BIBTEX_CMD%\r\n";
618 t<< "set ORG_BIBTEX_CMD=\r\n";
619 t<< "set MANUAL_FILE=%ORG_MANUAL_FILE%\r\n";
620 t<< "set ORG_MANUAL_FILE=\r\n";
621 t<< "set LATEX_COUNT=%ORG_LATEX_COUNT%\r\n";
622 t<< "set ORG_LATEX_COUNT=\r\n";
623 t<< "\r\n";
624 t<< ":end1\r\n";
625#endif
626}
627
629{
630 QCString dname = Config_getString(LATEX_OUTPUT);
631 Dir d(dname.str());
632 if (!d.exists() && !d.mkdir(dname.str()))
633 {
634 term("Could not create output directory %s\n",qPrint(dname));
635 }
636
637 if (!Config_getString(LATEX_HEADER).isEmpty())
638 {
640 //printf("g_header='%s'\n",qPrint(g_header));
641 QCString result = substituteLatexKeywords(g_header,QCString());
642 checkBlocks(result,Config_getString(LATEX_HEADER),latexMarkerInfo);
643 }
644 else
645 {
647 QCString result = substituteLatexKeywords(g_header,QCString());
648 checkBlocks(result,"<default header.tex>",latexMarkerInfo);
649 }
650 if (!Config_getString(LATEX_FOOTER).isEmpty())
651 {
653 //printf("g_footer='%s'\n",qPrint(g_footer));
654 QCString result = substituteLatexKeywords(g_footer,QCString());
655 checkBlocks(result,Config_getString(LATEX_FOOTER),latexMarkerInfo);
656 }
657 else
658 {
660 QCString result = substituteLatexKeywords(g_footer,QCString());
661 checkBlocks(result,"<default footer.tex>",latexMarkerInfo);
662 }
663
665 writeMakeBat();
666
667 createSubDirs(d);
668}
669
671{
672 QCString dname = Config_getString(LATEX_OUTPUT);
673 Dir d(dname.str());
674 clearSubDirs(d);
675}
676
678{
679 t << ResourceMgr::instance().getAsString("doxygen.sty");
680}
681
683{
684 t << "% Latex header for doxygen " << getDoxygenVersion() << "\n";
685 t << ResourceMgr::instance().getAsString("header.tex");
686}
687
689{
690 t << "% Latex footer for doxygen " << getDoxygenVersion() << "\n";
691 t << ResourceMgr::instance().getAsString("footer.tex");
692}
693
695{
696 t << "% stylesheet for doxygen " << getDoxygenVersion() << "\n";
698}
699
700void LatexGenerator::startFile(const QCString &name,const QCString &,const QCString &,int,int hierarchyLevel)
701{
702#if 0
703 setEncoding(Config_getString(LATEX_OUTPUT_ENCODING));
704#endif
705 QCString fileName=name;
706 m_hierarchyLevel = hierarchyLevel;
708 if (!fileName.endsWith(".tex") && !fileName.endsWith(".sty")) fileName+=".tex";
710 m_codeGen->setRelativePath(m_relPath);
711 m_codeGen->setSourceFileName(stripPath(fileName));
712}
713
715{
716 endPlainFile();
717 m_codeGen->setSourceFileName("");
718}
719
720//void LatexGenerator::writeIndex()
721//{
722// startFile("refman.tex");
723//}
724
726{
727 m_t << "\\\\[1ex]\\large ";
728}
729
731{
732 QCString result;
733 const StringVector &extraLatexStyles = Config_getList(LATEX_EXTRA_STYLESHEET);
734 for (const auto &fileName : extraLatexStyles)
735 {
736 if (!fileName.empty())
737 {
738 FileInfo fi(fileName);
739 if (fi.exists())
740 {
741 result += "\\usepackage{";
743 {
744 // strip the extension, it will be added by the usepackage in the tex conversion process
746 }
747 else
748 {
749 result += fi.fileName();
750 }
751 result += "}\n";
752 }
753 }
754 }
755 return result;
756}
757
759{
760 QCString result;
761 QCString latex_mkidx_command = Config_getString(LATEX_MAKEINDEX_CMD);
762 if (!latex_mkidx_command.isEmpty())
763 {
764 if (latex_mkidx_command[0] == '\\')
765 result += latex_mkidx_command;
766 else
767 result += "\\"+latex_mkidx_command;
768 }
769 else
770 {
771 result += "\\makeindex";
772 }
773 return result;
774}
775
777{
778 switch (Config_getEnum(LATEX_BATCHMODE))
779 {
780 case LATEX_BATCHMODE_t::NO: return "";
781 case LATEX_BATCHMODE_t::YES: return "\\batchmode";
782 case LATEX_BATCHMODE_t::BATCH: return "\\batchmode";
783 case LATEX_BATCHMODE_t::NON_STOP: return "\\nonstopmode";
784 case LATEX_BATCHMODE_t::SCROLL: return "\\scrollmode";
785 case LATEX_BATCHMODE_t::ERROR_STOP: return "\\errorstopmode";
786 }
787 return "";
788}
789
791 const QCString &title)
792{
793 bool compactLatex = Config_getBool(COMPACT_LATEX);
794 bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
795 bool usePdfLatex = Config_getBool(USE_PDFLATEX);
796 QCString paperType = Config_getEnumAsString(PAPER_TYPE);
797
798 QCString style = Config_getString(LATEX_BIB_STYLE);
799 if (style.isEmpty())
800 {
801 style="plainnat";
802 }
803
804 TextStream tg;
805 QCString generatedBy;
806 auto timeStamp = Config_getEnum(TIMESTAMP);
807 switch (timeStamp)
808 {
809 case TIMESTAMP_t::YES:
810 case TIMESTAMP_t::DATETIME:
811 generatedBy = theTranslator->trGeneratedAt(dateToString(DateTimeType::DateTime),
812 Config_getString(PROJECT_NAME));
813 break;
814 case TIMESTAMP_t::DATE:
815 generatedBy = theTranslator->trGeneratedAt(dateToString(DateTimeType::Date),
816 Config_getString(PROJECT_NAME));
817 break;
818 case TIMESTAMP_t::NO:
819 generatedBy = theTranslator->trGeneratedBy();
820 break;
821 }
822 filterLatexString(tg, generatedBy,
823 false, // insideTabbing
824 false, // insidePre
825 false, // insideItem
826 false, // insideTable
827 false // keepSpaces
828 );
829 generatedBy = tg.str();
830
831 QCString latexFontenc = theTranslator->latexFontenc();
832
833 QCString latexEmojiDirectory = Config_getString(LATEX_EMOJI_DIRECTORY);
834 if (latexEmojiDirectory.isEmpty()) latexEmojiDirectory = ".";
835 latexEmojiDirectory = substitute(latexEmojiDirectory,"\\","/");
836
837 TextStream tg1;
839 QCString extraLatexPackages = tg1.str();
840
841 TextStream tg2;
843 QCString latexSpecialFormulaChars = tg2.str();
844
845 QCString formulaMacrofile = Config_getString(FORMULA_MACROFILE);
846 QCString stripMacroFile;
847 if (!formulaMacrofile.isEmpty())
848 {
849 FileInfo fi(formulaMacrofile.str());
850 formulaMacrofile=fi.absFilePath();
851 stripMacroFile = fi.fileName();
852 copyFile(formulaMacrofile,Config_getString(LATEX_OUTPUT) + "/" + stripMacroFile);
853 }
854
855 QCString projectNumber = Config_getString(PROJECT_NUMBER);
856
857 // first substitute generic keywords
858 QCString result = substituteKeywords(str,title,
859 convertToLaTeX(Config_getString(PROJECT_NAME),false),
860 convertToLaTeX(projectNumber,false),
861 convertToLaTeX(Config_getString(PROJECT_BRIEF),false));
862
863 // additional LaTeX only keywords
864 result = substituteKeywords(result,
865 {
866 // keyword value getter
867 { "$latexdocumentpre", [&]() { return theTranslator->latexDocumentPre(); } },
868 { "$latexdocumentpost", [&]() { return theTranslator->latexDocumentPost(); } },
869 { "$generatedby", [&]() { return generatedBy; } },
870 { "$latexbibstyle", [&]() { return style; } },
871 { "$latexcitereference", [&]() { return theTranslator->trCiteReferences(); } },
872 { "$latexbibfiles", [&]() { return CitationManager::instance().latexBibFiles(); } },
873 { "$papertype", [&]() { return paperType+"paper"; } },
874 { "$extralatexstylesheet", [&]() { return extraLatexStyleSheet(); } },
875 { "$languagesupport", [&]() { return theTranslator->latexLanguageSupportCommand(); } },
876 { "$latexfontenc", [&]() { return latexFontenc; } },
877 { "$latexfont", [&]() { return theTranslator->latexFont(); } },
878 { "$latexemojidirectory", [&]() { return latexEmojiDirectory; } },
879 { "$makeindex", [&]() { return makeIndex(); } },
880 { "$extralatexpackages", [&]() { return extraLatexPackages; } },
881 { "$latexspecialformulachars", [&]() { return latexSpecialFormulaChars; } },
882 { "$formulamacrofile", [&]() { return stripMacroFile; } },
883 { "$latex_batchmode", [&]() { return latex_batchmode(); } }
884 });
885
886 // remove conditional blocks
887 result = selectBlocks(result,
888 {
889 // marker is enabled
890 { "CITATIONS_PRESENT", !CitationManager::instance().isEmpty() },
891 { "COMPACT_LATEX", compactLatex },
892 { "PDF_HYPERLINKS", pdfHyperlinks },
893 { "USE_PDFLATEX", usePdfLatex },
894 { "TIMESTAMP", timeStamp!=TIMESTAMP_t::NO },
895 { "LATEX_FONTENC", !latexFontenc.isEmpty() },
896 { "FORMULA_MACROFILE", !formulaMacrofile.isEmpty() },
897 { "PROJECT_NUMBER", !projectNumber.isEmpty() }
899
900 result = removeEmptyLines(result);
901
902 return result;
903}
904
906{
907 bool compactLatex = Config_getBool(COMPACT_LATEX);
908 switch (is)
909 {
912 break;
914 break;
916 break;
918 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
919 m_t << "{"; //Module Index}\n"
920 break;
922 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
923 m_t << "{"; //Topic Index}\n"
924 break;
926 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
927 m_t << "{"; //Directory Index}\n"
928 break;
930 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
931 m_t << "{"; //Namespace Index}\n"
932 break;
934 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
935 m_t << "{"; //Concept Index}\n"
936 break;
938 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
939 m_t << "{"; //Hierarchical Index}\n"
940 break;
942 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
943 m_t << "{"; //Annotated Compound Index}\n"
944 break;
946 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
947 m_t << "{"; //Annotated File Index}\n"
948 break;
950 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
951 m_t << "{"; //Annotated Page Index}\n"
952 break;
954 {
955 for (const auto &gd : *Doxygen::groupLinkedMap)
956 {
957 if (!gd->isReference())
958 {
959 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
960 m_t << "{"; //Topic Documentation}\n";
961 break;
962 }
963 }
964 }
965 break;
967 {
968 for (const auto &mod : ModuleManager::instance().modules())
969 {
970 if (!mod->isReference() && mod->isPrimaryInterface())
971 {
972 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
973 m_t << "{"; //Topic Documentation}\n";
974 break;
975 }
976 }
977 }
978 break;
980 {
981 for (const auto &dd : *Doxygen::dirLinkedMap)
982 {
983 if (dd->isLinkableInProject())
984 {
985 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
986 m_t << "{"; //Dir Documentation}\n";
987 break;
988 }
989 }
990 }
991 break;
993 {
994 for (const auto &nd : *Doxygen::namespaceLinkedMap)
995 {
996 if (nd->isLinkableInProject() && !nd->isAlias())
997 {
998 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
999 m_t << "{"; // Namespace Documentation}\n":
1000 break;
1001 }
1002 }
1003 }
1004 break;
1006 {
1007 for (const auto &cd : *Doxygen::conceptLinkedMap)
1008 {
1009 if (cd->isLinkableInProject() && !cd->isAlias())
1010 {
1011 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
1012 m_t << "{"; // Concept Documentation}\n":
1013 break;
1014 }
1015 }
1016 }
1017 break;
1019 {
1020 for (const auto &cd : *Doxygen::classLinkedMap)
1021 {
1022 if (cd->isLinkableInProject() &&
1023 cd->templateMaster()==nullptr &&
1024 !cd->isEmbeddedInOuterScope() &&
1025 !cd->isAlias()
1026 )
1027 {
1028 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
1029 m_t << "{"; //Compound Documentation}\n";
1030 break;
1031 }
1032 }
1033 }
1034 break;
1036 {
1037 bool isFirst=TRUE;
1038 for (const auto &fn : *Doxygen::inputNameLinkedMap)
1039 {
1040 for (const auto &fd : *fn)
1041 {
1042 if (fd->isLinkableInProject() || fd->generateSourceFile())
1043 {
1044 if (isFirst)
1045 {
1046 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
1047 m_t << "{"; //File Documentation}\n";
1048 isFirst=FALSE;
1049 break;
1050 }
1051 }
1052 }
1053 }
1054 }
1055 break;
1057 {
1058 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
1059 m_t << "{"; //Example Documentation}\n";
1060 }
1061 break;
1063 break;
1065 break;
1067 break;
1068 }
1069}
1070
1072{
1073 switch (is)
1074 {
1076 break;
1078 break;
1080 {
1082 {
1083 writePageLink(Doxygen::mainPage->getOutputFileBase(), FALSE);
1084 }
1085 }
1086 break;
1088 m_t << "}\n\\input{modules}\n";
1089 break;
1091 m_t << "}\n\\input{topics}\n";
1092 break;
1094 m_t << "}\n\\input{dirs}\n";
1095 break;
1097 m_t << "}\n\\input{namespaces}\n";
1098 break;
1100 m_t << "}\n\\input{concepts}\n";
1101 break;
1103 m_t << "}\n\\input{hierarchy}\n";
1104 break;
1106 m_t << "}\n\\input{annotated}\n";
1107 break;
1109 m_t << "}\n\\input{files}\n";
1110 break;
1112 m_t << "}\n\\input{pages}\n";
1113 break;
1115 {
1116 m_t << "}\n";
1117 for (const auto &gd : *Doxygen::groupLinkedMap)
1118 {
1119 if (!gd->isReference() && !gd->isASubGroup())
1120 {
1121 writePageLink(gd->getOutputFileBase(), FALSE);
1122 }
1123 }
1124 }
1125 break;
1127 {
1128 m_t << "}\n";
1129 for (const auto &mod : ModuleManager::instance().modules())
1130 {
1131 if (!mod->isReference() && mod->isPrimaryInterface())
1132 {
1133 writePageLink(mod->getOutputFileBase(), FALSE);
1134 }
1135 }
1136 }
1137 break;
1139 {
1140 bool found=FALSE;
1141 for (const auto &dd : *Doxygen::dirLinkedMap)
1142 {
1143 if (dd->isLinkableInProject())
1144 {
1145 if (!found)
1146 {
1147 m_t << "}\n";
1148 found = TRUE;
1149 }
1150 m_t << "\\input{" << dd->getOutputFileBase() << "}\n";
1151 }
1152 }
1153 }
1154 break;
1156 {
1157 bool found=FALSE;
1158 for (const auto &nd : *Doxygen::namespaceLinkedMap)
1159 {
1160 if (nd->isLinkableInProject() && !nd->isAlias())
1161 {
1162 if (!found)
1163 {
1164 m_t << "}\n";
1165 found=true;
1166 }
1167 m_t << "\\input{" << nd->getOutputFileBase() << "}\n";
1168 }
1169 }
1170 }
1171 break;
1173 {
1174 bool found=FALSE;
1175 for (const auto &cd : *Doxygen::conceptLinkedMap)
1176 {
1177 if (cd->isLinkableInProject() && !cd->isAlias())
1178 {
1179 if (!found)
1180 {
1181 m_t << "}\n";
1182 found=true;
1183 }
1184 m_t << "\\input{" << cd->getOutputFileBase() << "}\n";
1185 }
1186 }
1187 }
1188 break;
1190 {
1191 bool found=FALSE;
1192 for (const auto &cd : *Doxygen::classLinkedMap)
1193 {
1194 if (cd->isLinkableInProject() &&
1195 cd->templateMaster()==nullptr &&
1196 !cd->isEmbeddedInOuterScope() &&
1197 !cd->isAlias()
1198 )
1199 {
1200 if (!found)
1201 {
1202 m_t << "}\n"; // end doxysection or chapter title
1203 found=TRUE;
1204 }
1205 m_t << "\\input{" << cd->getOutputFileBase() << "}\n";
1206 }
1207 }
1208 }
1209 break;
1211 {
1212 bool isFirst=TRUE;
1213 for (const auto &fn : *Doxygen::inputNameLinkedMap)
1214 {
1215 for (const auto &fd : *fn)
1216 {
1217 if (fd->isLinkableInProject())
1218 {
1219 if (isFirst)
1220 {
1221 m_t << "}\n"; // end doxysection or chapter title
1222 }
1223 isFirst=FALSE;
1224 m_t << "\\input{" << fd->getOutputFileBase() << "}\n";
1225 }
1226 if (fd->generateSourceFile())
1227 {
1228 if (isFirst)
1229 {
1230 m_t << "}\n"; // end doxysection or chapter title
1231 }
1232 isFirst=FALSE;
1233 m_t << "\\input{" << fd->getSourceFileBase() << "}\n";
1234 }
1235 }
1236 }
1237 }
1238 break;
1240 {
1241 m_t << "}\n";
1242 for (const auto &pd : *Doxygen::exampleLinkedMap)
1243 {
1244 m_t << "\\input{" << pd->getOutputFileBase() << "}\n";
1245 }
1246 }
1247 break;
1249 {
1250 for (const auto &pd : *Doxygen::pageLinkedMap)
1251 {
1252 if (!pd->getGroupDef() && !pd->isReference() && !pd->hasParentPage()
1253 && pd->name() != "citelist" && Doxygen::mainPage.get() != pd.get())
1254 {
1255 writePageLink(pd->getOutputFileBase(), FALSE);
1256 }
1257 }
1258 }
1259 break;
1261 break;
1264 break;
1265 }
1266}
1267
1268void LatexGenerator::writePageLink(const QCString &name, bool /*first*/)
1269{
1270 //bool &compactLatex = Config_getBool(COMPACT_LATEX);
1271 // next is remove for bug615957
1272 //if (compactLatex || first) m_t << "\\input" ; else m_t << "\\include";
1273 m_t << "\\input" ;
1274 m_t << "{" << name << "}\n";
1275}
1276
1278{
1279 if (part > 0)
1280 return;
1281
1282 startPlainFile("doxygen.sty");
1284 endPlainFile();
1285
1286 // workaround for the problem caused by change in LaTeX in version 2019
1287 // in the unmaintained tabu package
1288 startPlainFile("tabu_doxygen.sty");
1289 m_t << ResourceMgr::instance().getAsString("tabu_doxygen.sty");
1290 endPlainFile();
1291 startPlainFile("longtable_doxygen.sty");
1292 m_t << ResourceMgr::instance().getAsString("longtable_doxygen.sty");
1293 endPlainFile();
1294 /// an extension of the etoc package is required that is only available in the
1295 /// newer version. Providing the updated version to be used with older versions
1296 /// of LaTeX
1297 startPlainFile("etoc_doxygen.sty");
1298 m_t << ResourceMgr::instance().getAsString("etoc_doxygen.sty");
1299 endPlainFile();
1300}
1301
1303{
1304 m_t << "\n" << "\n";
1305}
1306
1308{
1309 m_t << "\n" << "\n";
1310}
1311
1313{
1314 m_t << text;
1315}
1316
1318{
1319 m_t << "\\item ";
1320 if (ref.isEmpty() && !fn.isEmpty())
1321 {
1322 m_t << "\\contentsline{section}{";
1323 }
1324}
1325
1327{
1328 if (ref.isEmpty() && !fn.isEmpty())
1329 {
1330 m_t << "}{\\pageref{" << stripPath(fn) << "}}{}\n";
1331 }
1332}
1333
1335 const QCString &path,const QCString &name)
1336{
1337 m_t << "\\item\\contentsline{section}\\textbf{ ";
1338 if (!path.isEmpty()) docify(path);
1339 docify(name);
1340 m_t << "} ";
1341}
1342
1344{
1345 m_t << "\\item\\contentsline{section}{";
1346}
1347
1351
1353{
1354 m_t << " ";
1355 if (hasBrief) m_t << "\\\\*";
1356}
1357
1358void LatexGenerator::endIndexValue(const QCString &name,bool /*hasBrief*/)
1359{
1360 //if (hasBrief) m_t << ")";
1361 m_t << "}{\\pageref{" << stripPath(name) << "}}{}\n";
1362}
1363
1364//void LatexGenerator::writeClassLink(const QCString &,const QCString &,
1365// const QCString &,const QCString &name)
1366//{
1367// m_t << "\\textbf{ ";
1368// docify(name);
1369// m_t << "}";
1370//}
1371
1373{
1374 bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
1375 if (!m_disableLinks && pdfHyperlinks)
1376 {
1377 m_t << "\\mbox{\\hyperlink{";
1378 if (!f.isEmpty()) m_t << stripPath(f);
1379 if (!anchor.isEmpty()) m_t << "_" << anchor;
1380 m_t << "}{";
1381 }
1382 else
1383 {
1384 m_t << "\\textbf{ ";
1385 }
1386}
1387
1389{
1390 bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
1391 if (!m_disableLinks && pdfHyperlinks)
1392 {
1393 m_t << "}";
1394 }
1395 m_t << "}";
1396}
1397
1398static QCString objectLinkToString(const QCString &ref, const QCString &f,
1399 const QCString &anchor, const QCString &text,
1400 bool insideTabbing,bool disableLinks)
1401{
1402 bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
1403 QCString result;
1404 if (!disableLinks && ref.isEmpty() && pdfHyperlinks)
1405 {
1406 result += "\\mbox{\\hyperlink{";
1407 if (!f.isEmpty()) result += stripPath(f);
1408 if (!f.isEmpty() && !anchor.isEmpty()) result += "_";
1409 if (!anchor.isEmpty()) result += anchor;
1410 result += "}{";
1411 result += convertToLaTeX(text,insideTabbing);
1412 result += "}}";
1413 }
1414 else
1415 {
1416 result += "\\textbf{ ";
1417 result += convertToLaTeX(text,insideTabbing);
1418 result += "}";
1419 }
1420 return result;
1421}
1422
1423static void processEntity(TextStream &t, bool pdfHyperlinks, const char *strForm, const char *strRepl)
1424{
1425 if (pdfHyperlinks)
1426 {
1427 t << "\\texorpdfstring{";
1428 }
1429 t << strForm;
1430 if (pdfHyperlinks)
1431 {
1432 t << "}{" << strRepl << "}";
1433 }
1434}
1435
1437 const QCString &anchor, const QCString &text)
1438{
1439 m_t << objectLinkToString(ref,f,anchor,text,m_codeGen->insideTabbing(),m_disableLinks);
1440}
1441
1443{
1444 m_t << " \\doxyref{}{";
1445}
1446
1447void LatexGenerator::endPageRef(const QCString &clname, const QCString &anchor)
1448{
1449 m_t << "}{";
1450 if (!clname.isEmpty()) m_t << clname;
1451 if (!anchor.isEmpty()) m_t << "_" << anchor;
1452 m_t << "}";
1453}
1454
1455
1457{
1458 int hierarchyLevel = m_hierarchyLevel;
1459 if (Config_getBool(COMPACT_LATEX))
1460 {
1461 ++hierarchyLevel;
1462 }
1463
1464 if (hierarchyLevel < 0)
1465 m_t << "\\chapter{";
1466 else
1467 m_t << "\\doxy" << QCString("sub").repeat(hierarchyLevel) << "section{";
1468}
1469
1471{
1472 m_t << "}\n";
1473
1474 bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
1475 bool usePDFLatex = Config_getBool(USE_PDFLATEX);
1476 if (usePDFLatex && pdfHyperlinks && !fileName.isEmpty())
1477 {
1478 m_t << "\\hypertarget{" << stripPath(fileName) << "}{}";
1479 }
1480
1481 QCString fn = stripPath(fileName);
1482 if (!fn.isEmpty())
1483 {
1484 m_t << "\\label{" << fn << "}";
1485 }
1486 if (!name.isEmpty())
1487 {
1488 m_t << "\\index{";
1489 m_t << latexEscapeLabelName(name);
1490 m_t << "@{";
1491 m_t << latexEscapeIndexChars(name);
1492 m_t << "}}\n";
1493 }
1494}
1495
1497{
1498 if (Config_getBool(COMPACT_LATEX))
1499 {
1500 m_t << "\\doxysubsection{";
1501 }
1502 else
1503 {
1504 m_t << "\\doxysection{";
1505 }
1506}
1507
1508void LatexGenerator::startGroupHeader(int extraIndentLevel)
1509{
1510 if (Config_getBool(COMPACT_LATEX))
1511 {
1512 extraIndentLevel++;
1513 }
1514
1515 if (extraIndentLevel>=3)
1516 {
1517 m_t << "\\doxysubparagraph*{";
1518 }
1519 else if (extraIndentLevel==2)
1520 {
1521 m_t << "\\doxyparagraph{";
1522 }
1523 else
1524 {
1525 extraIndentLevel += m_hierarchyLevel + 1;
1526 m_t << "\\doxy" << QCString("sub").repeat(extraIndentLevel) << "section{";
1527 }
1529}
1530
1532{
1534 m_t << "}\n";
1535}
1536
1538{
1539 int l = m_hierarchyLevel + 1;
1540 if (Config_getBool(COMPACT_LATEX))
1541 {
1542 ++l;
1543 }
1544
1545 m_t << "\\doxysub" << QCString("sub").repeat(l) << "section*{";
1547}
1548
1550{
1552 m_t << "}\n";
1553}
1554
1556 const QCString &memname,
1557 const QCString &,
1558 const QCString &title,
1559 int memCount,
1560 int memTotal,
1561 bool showInline)
1562{
1563 if (!memname.isEmpty() && memname[0]!='@')
1564 {
1565 m_t << "\\index{";
1566 if (!clname.isEmpty())
1567 {
1568 m_t << latexEscapeLabelName(clname);
1569 m_t << "@{";
1570 m_t << latexEscapeIndexChars(clname);
1571 m_t << "}!";
1572 }
1573 m_t << latexEscapeLabelName(memname);
1574 m_t << "@{";
1575 m_t << latexEscapeIndexChars(memname);
1576 m_t << "}}\n";
1577
1578 m_t << "\\index{";
1579 m_t << latexEscapeLabelName(memname);
1580 m_t << "@{";
1581 m_t << latexEscapeIndexChars(memname);
1582 m_t << "}";
1583 if (!clname.isEmpty())
1584 {
1585 m_t << "!";
1586 m_t << latexEscapeLabelName(clname);
1587 m_t << "@{";
1588 m_t << latexEscapeIndexChars(clname);
1589 m_t << "}";
1590 }
1591 m_t << "}\n";
1592 }
1593 bool compactLatex = Config_getBool(COMPACT_LATEX);
1594 bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
1595 if (showInline)
1596 {
1597 m_t << "\\doxysubparagraph";
1598 }
1599 else if (compactLatex)
1600 {
1601 m_t << "\\doxyparagraph";
1602 }
1603 else
1604 {
1605 m_t << "\\doxy" << QCString("sub").repeat(m_hierarchyLevel + 2) << "section";
1606 }
1607
1608 m_t << "{";
1609 if (pdfHyperlinks)
1610 {
1611 m_t << "\\texorpdfstring{";
1612 }
1613 m_t << latexEscapeIndexChars(title);
1614 if (pdfHyperlinks)
1615 {
1616 m_t << "}{" << latexEscapePDFString(title) << "}";
1617 }
1618 if (memTotal>1)
1619 {
1620 m_t << "\\hspace{0.1cm}{\\footnotesize\\ttfamily [" << memCount << "/" << memTotal << "]}";
1621 }
1622 m_t << "}";
1623 m_t << "\n{\\footnotesize\\ttfamily ";
1624 //m_disableLinks=TRUE;
1625}
1626
1628{
1630 m_t << "}\n\n";
1631 //if (Config_getBool(COMPACT_LATEX)) m_t << "\\hfill";
1632}
1633
1635 const QCString &anchor, const QCString &,
1636 const QCString &)
1637{
1638 bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
1639 bool usePDFLatex = Config_getBool(USE_PDFLATEX);
1640 if (m_insideTableEnv) m_t << "\\mbox{"; // see issue #6093
1641 if (usePDFLatex && pdfHyperlinks)
1642 {
1643 m_t << "\\Hypertarget{";
1644 if (!fName.isEmpty()) m_t << stripPath(fName);
1645 if (!anchor.isEmpty()) m_t << "_" << anchor;
1646 m_t << "}";
1647 }
1648}
1649
1650void LatexGenerator::endDoxyAnchor(const QCString &/* fName */,const QCString &/* anchor */)
1651{
1652}
1653
1654void LatexGenerator::addLabel(const QCString &fName, const QCString &anchor)
1655{
1656 m_t << "\\label{";
1657 if (!fName.isEmpty()) m_t << stripPath(fName);
1658 if (!anchor.isEmpty()) m_t << "_" << anchor;
1659 if (m_insideTableEnv) m_t << "}";
1660 m_t << "} \n";
1661}
1662
1663void LatexGenerator::writeAnchor(const QCString &fName,const QCString &name)
1664{
1665 //printf("LatexGenerator::writeAnchor(%s,%s)\n",fName,name);
1666 m_t << "\\label{" << stripPath(name) << "}\n";
1667 bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
1668 bool usePDFLatex = Config_getBool(USE_PDFLATEX);
1669 if (usePDFLatex && pdfHyperlinks)
1670 {
1671 if (!fName.isEmpty())
1672 {
1673 m_t << "\\Hypertarget{" << stripPath(fName) << "_" << stripPath(name) << "}\n";
1674 }
1675 else
1676 {
1677 m_t << "\\Hypertarget{" << stripPath(name) << "}\n";
1678 }
1679 }
1680}
1681
1682
1683//void LatexGenerator::writeLatexLabel(const QCString &clName,const QCString &anchor)
1684//{
1685// writeDoxyAnchor(0,clName,anchor,0);
1686//}
1687
1689{
1690 if (!s1.isEmpty())
1691 {
1692 m_t << "\\index{";
1694 m_t << "@{";
1696 m_t << "}";
1697 if (!s2.isEmpty())
1698 {
1699 m_t << "!";
1701 m_t << "@{";
1703 m_t << "}";
1704 }
1705 m_t << "}";
1706 }
1707}
1708
1709
1711{
1712 bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
1713 bool usePDFLatex = Config_getBool(USE_PDFLATEX);
1714 if (usePDFLatex && pdfHyperlinks)
1715 {
1716 m_t << "\\hypertarget{" << stripPath(lab) << "}{}";
1717 }
1718 m_t << "\\";
1719 if (Config_getBool(COMPACT_LATEX))
1720 {
1721 switch(type.level())
1722 {
1723 case SectionType::Page: m_t << "doxysubsection"; break;
1724 case SectionType::Section: m_t << "doxysubsubsection"; break;
1725 case SectionType::Subsection: m_t << "doxysubsubsubsection"; break;
1726 case SectionType::Subsubsection: m_t << "doxysubsubsubsubsection"; break;
1727 case SectionType::Paragraph: m_t << "doxysubsubsubsubsubsection"; break;
1728 case SectionType::Subparagraph: m_t << "doxysubsubsubsubsubsubsection"; break;
1729 case SectionType::Subsubparagraph: m_t << "doxysubsubsubsubsubsubsection"; break;
1730 default: ASSERT(0); break;
1731 }
1732 m_t << "{";
1733 }
1734 else
1735 {
1736 switch(type.level())
1737 {
1738 case SectionType::Page: m_t << "doxysection"; break;
1739 case SectionType::Section: m_t << "doxysubsection"; break;
1740 case SectionType::Subsection: m_t << "doxysubsubsection"; break;
1741 case SectionType::Subsubsection: m_t << "doxysubsubsubsection"; break;
1742 case SectionType::Paragraph: m_t << "doxysubsubsubsubsection"; break;
1743 case SectionType::Subparagraph: m_t << "doxysubsubsubsubsubsection"; break;
1744 case SectionType::Subsubparagraph: m_t << "doxysubsubsubsubsubsubsection"; break;
1745 default: ASSERT(0); break;
1746 }
1747 m_t << "{";
1748 }
1749}
1750
1752{
1753 m_t << "}\\label{" << lab << "}\n";
1754}
1755
1756
1758{
1760 m_codeGen->insideTabbing(), // insideTabbing
1761 false, // insidePre
1762 false, // insideItem
1763 m_codeGen->usedTableLevel()>0, // insideTable
1764 false // keepSpaces
1765 );
1766}
1767
1769{
1770 char cs[2];
1771 cs[0]=c;
1772 cs[1]=0;
1773 docify(cs);
1774}
1775
1777{
1778 //if (Config_getBool(COMPACT_LATEX)) m_t << "\\doxysubsubsection"; else m_t << "\\doxysubsection";
1779 //m_t << "{";
1780}
1781
1783 const QCString &fileName,const QCString &)
1784{
1786}
1787
1788
1790{
1791 if (indent==0)
1792 {
1793 m_t << "\\begin{tabbing}\n";
1794 m_t << "xx\\=xx\\=xx\\=xx\\=xx\\=xx\\=xx\\=xx\\=xx\\=\\kill\n";
1795 m_codeGen->setInsideTabbing(true);
1796 }
1797 m_indent=indent;
1798}
1799
1801{
1802 if (indent==0)
1803 {
1804 m_t << "\n" << "\\end{tabbing}";
1805 m_codeGen->setInsideTabbing(false);
1806 }
1807 m_indent=indent;
1808}
1809
1811{
1813 {
1814 m_t << "{\\footnotesize ";
1815 }
1816}
1817
1819{
1821 {
1822 m_t << "}\\\\";
1823 }
1824}
1825
1827{
1828 //printf("LatexGenerator::startMemberItem(%d)\n",annType);
1829 if (!m_codeGen->insideTabbing())
1830 {
1831 m_t << "\\item \n";
1833 }
1834}
1835
1837{
1838 if (m_codeGen->insideTabbing())
1839 {
1840 m_t << "\\\\";
1841 }
1843 m_t << "\n";
1844}
1845
1847{
1848 if (!m_codeGen->insideTabbing())
1849 {
1850 m_t << "\\begin{DoxyCompactList}\\small\\item\\em ";
1851 }
1852 else
1853 {
1854 for (int i=0;i<m_indent+2;i++) m_t << "\\>";
1855 m_t << "{\\em ";
1856 }
1857}
1858
1860{
1861 if (!m_codeGen->insideTabbing())
1862 {
1863 //m_t << "\\item\\end{DoxyCompactList}";
1864 m_t << "\\end{DoxyCompactList}";
1865 }
1866 else
1867 {
1868 m_t << "}\\\\\n";
1869 }
1870}
1871
1872
1874{
1875 //printf("writeNonBreakableSpace()\n");
1876 if (m_codeGen->insideTabbing())
1877 {
1878 m_t << "\\>";
1879 }
1880 else
1881 {
1882 m_t << "~";
1883 }
1884}
1885
1886// ----------------------------------------------
1887// nesting of functions below:
1888// startDescTable()
1889// - startDescTableRow()
1890// - startDescTableTitle()
1891// - endDescTableTitle()
1892// - startDescTableData()
1893// - endDescTableData()
1894// - endDescTableRow()
1895// - startDescTableRow()
1896// - ...
1897// - endDescTableRow()
1898// endDescTable()
1899
1900void LatexGenerator::startDescTable(const QCString &title,const bool hasInits)
1901{
1902 m_codeGen->incUsedTableLevel();
1903 m_t << "\\begin{DoxyEnumFields}[" << (hasInits?3:2) << "]{" << title << "}\n";
1904}
1905
1907{
1908 m_codeGen->decUsedTableLevel();
1909 m_t << "\\end{DoxyEnumFields}\n";
1910}
1911
1913{
1914 // this is needed to prevent the \hypertarget, \label, and \index commands from messing up
1915 // the row height (based on http://tex.stackexchange.com/a/186102)
1916 m_t << "\\raisebox{\\heightof{T}}[0pt][0pt]{";
1917}
1918
1922
1924{
1925 m_t << "}";
1926}
1927
1931
1933{
1934 m_t << "&";
1935}
1936
1940
1942{
1943 m_t << "&";
1944}
1945
1947{
1948 m_t << "\\\\\n\\hline\n\n";
1949}
1950
1954
1955
1957{
1958 if (!m_codeGen->insideTabbing())
1959 {
1960 m_t << "\\begin{DoxyCompactItemize}\n";
1961 }
1962}
1963
1965{
1966 //printf("LatexGenerator::endMemberList(%d)\n",m_codeGen->InsideTabbing());
1967 if (!m_codeGen->insideTabbing())
1968 {
1969 m_t << "\\end{DoxyCompactItemize}\n";
1970 }
1971}
1972
1973
1975{
1976 if (hasHeader) m_t << "\\begin{Indent}";
1977 m_t << "\\textbf{ ";
1978 // changed back to rev 756 due to bug 660501
1979 //if (Config_getBool(COMPACT_LATEX))
1980 //{
1981 // m_t << "\\doxysubparagraph*{";
1982 //}
1983 //else
1984 //{
1985 // m_t << "\\doxyparagraph*{";
1986 //}
1987}
1988
1990{
1991 // changed back to rev 756 due to bug 660501
1992 m_t << "}\\par\n";
1993 //m_t << "}\n";
1994}
1995
1997{
1998 m_t << "{\\em ";
1999}
2000
2002{
2003 m_t << "}";
2004}
2005
2009
2011{
2012 if (hasHeader)m_t << "\\end{Indent}";
2013 m_t << "\n";
2014}
2015
2017{
2018 m_t << "\n" << "\n";
2019}
2020
2025
2029
2034
2038
2043
2047
2052
2056
2061
2063{
2064 m_t << "\\begin{Desc}\n\\item[";
2066 m_t << "]";
2067}
2068
2070{
2071 m_t << "\\end{Desc}\n";
2072}
2073
2075{
2076 /* start of ParameterType ParameterName list */
2077 if (openBracket) m_t << "(";
2078 m_t << "\\begin{DoxyParamCaption}";
2079}
2080
2084
2086{
2087 m_t << "\\item[{";
2088 if (!first && !key.isEmpty()) docify(key);
2089}
2090
2092{
2093 m_t << "}]";
2094}
2095
2096void LatexGenerator::startParameterName(bool /*oneArgOnly*/)
2097{
2098 m_t << "{";
2099}
2100
2102{
2103 m_t << "}";
2104}
2105
2107{
2108 m_t << "{";
2109}
2110
2111void LatexGenerator::endParameterExtra(bool last,bool /*emptyList*/,bool closeBracket)
2112{
2113 m_t << "}";
2114 if (last)
2115 {
2116 m_t << "\\end{DoxyParamCaption}";
2117 if (closeBracket) m_t << ")";
2118 }
2119}
2120
2121void LatexGenerator::exceptionEntry(const QCString &prefix,bool closeBracket)
2122{
2123 if (!prefix.isEmpty())
2124 {
2125 m_t << " " << prefix << "(";
2126 }
2127 else if (closeBracket)
2128 {
2129 m_t << ")";
2130 }
2131 m_t << " ";
2132}
2133
2134void LatexGenerator::writeDoc(const IDocNodeAST *ast,const Definition *ctx,const MemberDef *,int)
2135{
2136 const DocNodeAST *astImpl = dynamic_cast<const DocNodeAST*>(ast);
2137 if (astImpl)
2138 {
2139 LatexDocVisitor visitor(m_t,*m_codeList,*m_codeGen,
2140 ctx?ctx->getDefFileExtension():QCString(""),
2142 std::visit(visitor,astImpl->root);
2143 }
2144}
2145
2147{
2148 m_t << "\\begin{Desc}\n\\item[";
2149 docify(header);
2150 m_t << "]";
2151 m_t << "\\begin{description}\n";
2152}
2153
2155{
2156 m_t << "\\item[{\\em ";
2157}
2158
2162
2164{
2165 m_t << "} : {\\em ";
2166}
2167
2169{
2170 m_t << "}]";
2171}
2172
2176
2180
2182{
2183 m_t << "\\end{description}\n";
2184 m_t << "\\end{Desc}\n";
2185}
2186
2188{
2189 if (Config_getBool(COMPACT_LATEX))
2190 {
2191 m_t << "\\doxyparagraph*{";
2192 }
2193 else
2194 {
2195 m_t << "\\doxy" << QCString("sub").repeat(m_hierarchyLevel + 1) << "section*{";
2196 }
2197}
2198
2200{
2201 m_t << "}\n";
2202}
2203
2205{
2206 if (m_codeGen->insideTabbing())
2207 {
2208 m_t << "\\\\\n";
2209 }
2210 else
2211 {
2212 m_t << "\\newline\n";
2213 }
2214}
2215
2217{
2218 m_codeGen->incUsedTableLevel();
2219 if (isEnum)
2220 {
2221 m_t << "\\begin{DoxyEnumFields}{";
2223 }
2224 else
2225 {
2226 m_t << "\\begin{DoxyFields}{";
2228 }
2229 m_t << "}\n";
2230 m_insideTableEnv=true;
2231}
2232
2234{
2235 m_insideTableEnv=false;
2236 m_codeGen->decUsedTableLevel();
2237 if (isEnum)
2238 {
2239 m_t << "\\end{DoxyEnumFields}\n";
2240 }
2241 else
2242 {
2243 m_t << "\\end{DoxyFields}\n";
2244 }
2245}
2246
2248{
2249 m_codeGen->setInsideTabbing(true); // to prevent \+ from causing unwanted breaks
2250}
2251
2253{
2254 m_t << "&\n";
2255 m_codeGen->setInsideTabbing(false);
2256}
2257
2259{
2260 m_codeGen->setInsideTabbing(true); // to prevent \+ from causing unwanted breaks
2261}
2262
2264{
2265 m_t << "&\n";
2266 m_codeGen->setInsideTabbing(false);
2267}
2268
2272
2274{
2275 m_t << "\\\\\n\\hline\n\n";
2276}
2277
2279{
2280 m_t << "\\hspace{0.3cm}";
2281}
2282
2283void LatexGenerator::writeLabel(const QCString &l,bool isLast)
2284{
2285 m_t << "{\\ttfamily [" << l << "]}";
2286 if (!isLast) m_t << ", ";
2287}
2288
2290{
2291}
2292
2294 const QCString &/*id*/,const QCString &ref,
2295 const QCString &file, const QCString &anchor,
2296 const QCString &title, const QCString &name)
2297{
2298 if (Config_getBool(COMPACT_LATEX))
2299 {
2300 m_t << "\\doxyparagraph*{";
2301 }
2302 else
2303 {
2304 m_t << "\\doxy" << QCString("sub").repeat(m_hierarchyLevel + 1) << "section*{";
2305 }
2306 m_t << theTranslator->trInheritedFrom(convertToLaTeX(title,m_codeGen->insideTabbing()),
2307 objectLinkToString(ref, file, anchor, name, m_codeGen->insideTabbing(), m_disableLinks));
2308 m_t << "}\n";
2309}
2310
2312{
2313 if (localToc.isLatexEnabled())
2314 {
2315 int maxLevel = localToc.latexLevel() + m_hierarchyLevel;
2316 m_t << "\\etocsetnexttocdepth{" << maxLevel << "}\n";
2317 m_t << "\\localtableofcontents\n";
2318 }
2319}
2320
2321//--------------------------------------------------------------------------------------------------
2322
2324{
2325 // User-specified packages
2326 const StringVector &extraPackages = Config_getList(EXTRA_PACKAGES);
2327 if (!extraPackages.empty())
2328 {
2329 t << "% Packages requested by user\n";
2330 for (const auto &pkgName : extraPackages)
2331 {
2332 if ((pkgName[0] == '[') || (pkgName[0] == '{'))
2333 t << "\\usepackage" << pkgName.c_str() << "\n";
2334 else
2335 t << "\\usepackage{" << pkgName.c_str() << "}\n";
2336 }
2337 t << "\n";
2338 }
2339}
2340
2342{
2343 unsigned char minus[4]; // Superscript minus
2344 unsigned char sup2[3]; // Superscript two
2345 unsigned char sup3[3];
2346 minus[0]= 0xE2;
2347 minus[1]= 0x81;
2348 minus[2]= 0xBB;
2349 minus[3]= 0;
2350 sup2[0]= 0xC2;
2351 sup2[1]= 0xB2;
2352 sup2[2]= 0;
2353 sup3[0]= 0xC2;
2354 sup3[1]= 0xB3;
2355 sup3[2]= 0;
2356
2357 t << "\\ifPDFTeX\n";
2358 t << "\\usepackage{newunicodechar}\n";
2359 // taken from the newunicodechar package and removed the warning message
2360 // actually forcing to redefine the unicode character
2361 t << " \\makeatletter\n"
2362 " \\def\\doxynewunicodechar#1#2{%\n"
2363 " \\@tempswafalse\n"
2364 " \\edef\\nuc@tempa{\\detokenize{#1}}%\n"
2365 " \\if\\relax\\nuc@tempa\\relax\n"
2366 " \\nuc@emptyargerr\n"
2367 " \\else\n"
2368 " \\edef\\@tempb{\\expandafter\\@car\\nuc@tempa\\@nil}%\n"
2369 " \\nuc@check\n"
2370 " \\if@tempswa\n"
2371 " \\@namedef{u8:\\nuc@tempa}{#2}%\n"
2372 " \\fi\n"
2373 " \\fi\n"
2374 " }\n"
2375 " \\makeatother\n";
2376
2377 t << " \\doxynewunicodechar{" << minus << "}{${}^{-}$}% Superscript minus\n"
2378 " \\doxynewunicodechar{" << sup2 << "}{${}^{2}$}% Superscript two\n"
2379 " \\doxynewunicodechar{" << sup3 << "}{${}^{3}$}% Superscript three\n"
2380 "\n";
2381 t << "\\fi\n";
2382}
2383
2385 bool insideTabbing,bool insidePre,bool insideItem,bool insideTable,bool keepSpaces, const bool retainNewline)
2386{
2387 if (str.isEmpty()) return;
2388 bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
2389 //printf("filterLatexString(%s) insideTabbing=%d\n",qPrint(str),insideTabbing);
2390 const char *p = str.data();
2391 const char *q = nullptr;
2392 unsigned char pc='\0';
2393
2394 while (*p)
2395 {
2396 unsigned char c=static_cast<unsigned char>(*p++);
2397
2398 if (insidePre)
2399 {
2400 switch(c)
2401 {
2402 case 0xef: // handle U+FFFD i.e. "Replacement character" caused by octal: 357 277 275 / hexadecimal 0xef 0xbf 0xbd
2403 // the LaTeX command \ucr has been defined in doxygen.sty
2404 if (static_cast<unsigned char>(*(p)) == 0xbf && static_cast<unsigned char>(*(p+1)) == 0xbd)
2405 {
2406 t << "{\\ucr}";
2407 p += 2;
2408 }
2409 else
2410 t << static_cast<char>(c);
2411 break;
2412 case '\\': t << "\\(\\backslash\\)"; break;
2413 case '{': t << "\\{"; break;
2414 case '}': t << "\\}"; break;
2415 case '_': t << "\\_"; break;
2416 case '&': t << "\\&"; break;
2417 case '%': t << "\\%"; break;
2418 case '#': t << "\\#"; break;
2419 case '$': t << "\\$"; break;
2420 case '"': t << "\"{}"; break;
2421 case '-': t << "-\\/"; break;
2422 case '^': insideTable ? t << "\\string^" : t << static_cast<char>(c); break;
2423 case '~': t << "\\string~"; break;
2424 case '\n': if (retainNewline) t << "\\newline"; else t << ' ';
2425 break;
2426 case ' ': if (keepSpaces) t << "~"; else t << ' ';
2427 break;
2428 default:
2429 if (c<32) t << ' '; // non printable control character
2430 else t << static_cast<char>(c);
2431 break;
2432 }
2433 }
2434 else
2435 {
2436 switch(c)
2437 {
2438 case 0xef: // handle U+FFFD i.e. "Replacement character" caused by octal: 357 277 275 / hexadecimal 0xef 0xbf 0xbd
2439 // the LaTeX command \ucr has been defined in doxygen.sty
2440 if (static_cast<unsigned char>(*(p)) == 0xbf && static_cast<unsigned char>(*(p+1)) == 0xbd)
2441 {
2442 t << "{\\ucr}";
2443 p += 2;
2444 }
2445 else
2446 t << static_cast<char>(c);
2447 break;
2448 case '#': t << "\\#"; break;
2449 case '$': t << "\\$"; break;
2450 case '%': t << "\\%"; break;
2451 case '^': processEntity(t,pdfHyperlinks,"$^\\wedge$","\\string^"); break;
2452 case '&': {
2453 // possibility to have a special symbol
2454 q = p;
2455 int cnt = 2; // we have to count & and ; as well
2456 while ((*q >= 'a' && *q <= 'z') || (*q >= 'A' && *q <= 'Z') || (*q >= '0' && *q <= '9'))
2457 {
2458 cnt++;
2459 q++;
2460 }
2461 if (*q == ';')
2462 {
2463 --p; // we need & as well
2466 {
2467 p++;
2468 t << "\\&";
2469 }
2470 else
2471 {
2473 q++;
2474 p = q;
2475 }
2476 }
2477 else
2478 {
2479 t << "\\&";
2480 }
2481 }
2482 break;
2483 case '*': processEntity(t,pdfHyperlinks,"$\\ast$","*"); break;
2484 case '_': if (!insideTabbing) t << "\\+";
2485 t << "\\_";
2486 if (!insideTabbing) t << "\\+";
2487 break;
2488 case '{': t << "\\{"; break;
2489 case '}': t << "\\}"; break;
2490 case '<': t << "$<$"; break;
2491 case '>': t << "$>$"; break;
2492 case '|': processEntity(t,pdfHyperlinks,"$\\vert$","|"); break;
2493 case '~': processEntity(t,pdfHyperlinks,"$\\sim$","\\string~"); break;
2494 case '[': if (Config_getBool(PDF_HYPERLINKS) || insideItem)
2495 t << "\\mbox{[}";
2496 else
2497 t << "[";
2498 break;
2499 case ']': if (pc=='[') t << "$\\,$";
2500 if (Config_getBool(PDF_HYPERLINKS) || insideItem)
2501 t << "\\mbox{]}";
2502 else
2503 t << "]";
2504 break;
2505 case '-': t << "-\\/";
2506 break;
2507 case '\\': t << "\\textbackslash{}";
2508 break;
2509 case '"': t << "\"{}";
2510 break;
2511 case '`': t << "\\`{}";
2512 break;
2513 case '\'': t << "\\textquotesingle{}";
2514 break;
2515 case '\n': if (retainNewline) t << "\\newline"; else t << ' ';
2516 break;
2517 case ' ': if (keepSpaces) { if (insideTabbing) t << "\\>"; else t << '~'; } else t << ' ';
2518 break;
2519
2520 default:
2521 //if (!insideTabbing && forceBreaks && c!=' ' && *p!=' ')
2522 if (!insideTabbing &&
2523 ((c>='A' && c<='Z' && pc!=' ' && !(pc>='A' && pc <= 'Z') && pc!='\0' && *p) || (c==':' && pc!=':') || (pc=='.' && isId(c)))
2524 )
2525 {
2526 t << "\\+";
2527 }
2528 if (c<32)
2529 {
2530 t << ' '; // non-printable control character
2531 }
2532 else
2533 {
2534 t << static_cast<char>(c);
2535 }
2536 }
2537 }
2538 pc = c;
2539 }
2540}
2541
2542QCString convertToLaTeX(const QCString &s,bool insideTabbing,bool keepSpaces)
2543{
2544 TextStream t;
2545 filterLatexString(t,s,insideTabbing,false,false,false,keepSpaces);
2546 return t.str();
2547}
2548
2550{
2551 //printf("latexEscapeLabelName(%s)\n",qPrint(s));
2552 if (s.isEmpty()) return s;
2554 TextStream t;
2555 const char *p=s.data();
2556 char c = 0;
2557 while ((c=*p++))
2558 {
2559 switch (c)
2560 {
2561 case '|': t << "\\texttt{\"|}"; break;
2562 case '!': t << "\"!"; break;
2563 case '@': t << "\"@"; break;
2564 case '%': t << "\\%"; break;
2565 case '{': t << "\\lcurly{}"; break;
2566 case '}': t << "\\rcurly{}"; break;
2567 case '~': t << "````~"; break; // to get it a bit better in index together with other special characters
2568 // NOTE: adding a case here, means adding it to while below as well!
2569 default:
2570 {
2571 int i=0;
2572 // collect as long string as possible, before handing it to docify
2573 tmp[i++]=c;
2574 while ((c=*p) && c!='@' && c!='[' && c!=']' && c!='!' && c!='{' && c!='}' && c!='|')
2575 {
2576 tmp[i++]=c;
2577 p++;
2578 }
2579 tmp[i]=0;
2580 filterLatexString(t,tmp,
2581 true, // insideTabbing
2582 false, // insidePre
2583 false, // insideItem
2584 false, // insideTable
2585 false // keepSpaces
2586 );
2587 }
2588 break;
2589 }
2590 }
2591 return t.str();
2592}
2593
2595{
2596 //printf("latexEscapeIndexChars(%s)\n",qPrint(s));
2597 if (s.isEmpty()) return s;
2599 TextStream t;
2600 const char *p=s.data();
2601 char c = 0;
2602 while ((c=*p++))
2603 {
2604 switch (c)
2605 {
2606 case '!': t << "\"!"; break;
2607 case '"': t << "\"\""; break;
2608 case '@': t << "\"@"; break;
2609 case '|': t << "\\texttt{\"|}"; break;
2610 case '[': t << "["; break;
2611 case ']': t << "]"; break;
2612 case '{': t << "\\lcurly{}"; break;
2613 case '}': t << "\\rcurly{}"; break;
2614 // NOTE: adding a case here, means adding it to while below as well!
2615 default:
2616 {
2617 int i=0;
2618 // collect as long string as possible, before handing it to docify
2619 tmp[i++]=c;
2620 while ((c=*p) && c!='"' && c!='@' && c!='[' && c!=']' && c!='!' && c!='{' && c!='}' && c!='|')
2621 {
2622 tmp[i++]=c;
2623 p++;
2624 }
2625 tmp[i]=0;
2626 filterLatexString(t,tmp,
2627 true, // insideTabbing
2628 false, // insidePre
2629 false, // insideItem
2630 false, // insideTable
2631 false // keepSpaces
2632 );
2633 }
2634 break;
2635 }
2636 }
2637 return t.str();
2638}
2639
2641{
2642 if (s.isEmpty()) return s;
2643 TextStream t;
2644 const char *p=s.data();
2645 char c = 0;
2646 while ((c=*p++))
2647 {
2648 switch (c)
2649 {
2650 case '\\': t << "\\textbackslash{}"; break;
2651 case '{': t << "\\{"; break;
2652 case '}': t << "\\}"; break;
2653 case '_': t << "\\_"; break;
2654 case '%': t << "\\%"; break;
2655 case '&': t << "\\&"; break;
2656 case '#': t << "\\#"; break;
2657 case '$': t << "\\$"; break;
2658 case '^': t << "\\string^"; break;
2659 case '~': t << "\\string~"; break;
2660 default:
2661 t << c;
2662 break;
2663 }
2664 }
2665 return t.str();
2666}
2667
2669{
2670 constexpr auto hex = "0123456789ABCDEF";
2671 if (s.isEmpty()) return s;
2672 TextStream t;
2673 const char *p=s.data();
2674 char c = 0;
2675 while ((c=*p++))
2676 {
2677 switch (c)
2678 {
2679 case '#': t << "\\#"; break;
2680 case '%': t << "\\%"; break;
2681 case '\\': t << "\\\\"; break;
2682 default:
2683 if (c<0)
2684 {
2685 unsigned char id = static_cast<unsigned char>(c);
2686 t << "\\%" << hex[id>>4] << hex[id&0xF];
2687 }
2688 else
2689 {
2690 t << c;
2691 }
2692 break;
2693 }
2694 }
2695 return t.str();
2696}
2697
2698
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
bool mkdir(const std::string &path, bool acceptsAbsPath=true) const
Definition dir.cpp:295
bool exists() const
Definition dir.cpp:257
DocNodeVariant root
Definition docnode.h:1467
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
bool m_stripCodeComments
Definition latexgen.h:87
TextStream * m_t
Definition latexgen.h:80
void setStripIndentAmount(size_t amount) override
Definition latexgen.cpp:189
void endFontClass() override
Definition latexgen.cpp:295
void writeLineNumber(const QCString &, const QCString &, const QCString &, int, bool) override
Definition latexgen.cpp:220
void setSourceFileName(const QCString &sourceFileName)
Definition latexgen.cpp:71
void setRelativePath(const QCString &path)
Definition latexgen.cpp:66
void startFontClass(const QCString &) override
Definition latexgen.cpp:289
void endSpecialComment() override
Definition latexgen.cpp:184
void stripCodeComments(bool b) override
Definition latexgen.cpp:174
void startCodeFragment(const QCString &style) override
Definition latexgen.cpp:301
size_t m_stripIndentAmount
Definition latexgen.h:89
void startCodeLine(int) override
Definition latexgen.cpp:267
LatexCodeGenerator(TextStream *t, const QCString &relPath, const QCString &sourceFile)
Definition latexgen.cpp:57
void startSpecialComment() override
Definition latexgen.cpp:179
void endCodeFragment(const QCString &style) override
Definition latexgen.cpp:306
QCString m_sourceFileName
Definition latexgen.h:82
void codify(const QCString &text) override
Definition latexgen.cpp:76
void endCodeLine() override
Definition latexgen.cpp:278
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:194
bool m_doxyCodeLineOpen
Definition latexgen.h:84
void endMemberItem(MemberItemType) override
void addCodeGen(OutputCodeList &list) override
Definition latexgen.cpp:357
void endIndexKey() override
void endInlineMemberDoc() override
void startProjectNumber() override
Definition latexgen.cpp:725
void cleanup() override
Definition latexgen.cpp:670
void endPageRef(const QCString &, const QCString &) override
void endSection(const QCString &, SectionType) override
void startIndexSection(IndexSection) override
Definition latexgen.cpp:905
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:688
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:694
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:714
void startExamples() override
LatexGenerator & operator=(const LatexGenerator &)
Definition latexgen.cpp:337
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:700
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:682
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:628
void startMemberGroupHeader(bool) override
bool m_templateMemberItem
Definition latexgen.h:326
int latexLevel() const
Definition types.h:459
bool isLatexEnabled() const
Definition types.h:454
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
const std::string & str() const
Definition qcstring.h:526
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
virtual QCString trInheritedFrom(const QCString &members, const QCString &what)=0
virtual QCString trEnumerationValues()=0
virtual QCString trCompoundMembers()=0
virtual QCString trExamples()=0
#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:63
static QCString g_footer
Definition htmlgen.cpp:64
static void writeDefaultStyleSheet(TextStream &t)
Definition htmlgen.cpp:1388
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:776
QCString latexEscapePDFString(const QCString &s)
QCString convertToLaTeX(const QCString &s, bool insideTabbing, bool keepSpaces)
static QCString makeIndex()
Definition latexgen.cpp:758
QCString latexFilterURL(const QCString &s)
static void writeLatexMakefile()
Definition latexgen.cpp:362
static QCString substituteLatexKeywords(const QCString &str, const QCString &title)
Definition latexgen.cpp:790
static const SelectionMarkerInfo latexMarkerInfo
Definition latexgen.cpp:53
static QCString extraLatexStyleSheet()
Definition latexgen.cpp:730
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:498
static void writeDefaultStyleSheet(TextStream &t)
Definition latexgen.cpp:677
void writeExtraLatexPackages(TextStream &t)
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:94
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
const char * qPrint(const char *s)
Definition qcstring.h:661
#define TRUE
Definition qcstring.h:37
#define FALSE
Definition qcstring.h:34
#define ASSERT(x)
Definition qcstring.h:39
CodeSymbolType
Definition types.h:319
Various UTF8 related helper functions.
size_t updateColumnCount(const char *s, size_t col)
Definition util.cpp:7207
void checkBlocks(const QCString &s, const QCString fileName, const SelectionMarkerInfo &markerInfo)
Definition util.cpp:6849
QCString stripPath(const QCString &s)
Definition util.cpp:5292
QCString removeEmptyLines(const QCString &s)
Definition util.cpp:6913
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:6736
QCString relativePathToRoot(const QCString &name)
Definition util.cpp:3933
void clearSubDirs(const Dir &d)
Definition util.cpp:4021
bool found
Definition util.cpp:984
QCString fileToString(const QCString &name, bool filter, bool isSourceCode)
Definition util.cpp:1414
QCString stripExtensionGeneral(const QCString &fName, const QCString &ext)
Definition util.cpp:5255
void createSubDirs(const Dir &d)
Definition util.cpp:3994
bool checkExtension(const QCString &fName, const QCString &ext)
Definition util.cpp:5238
QCString substituteKeywords(const QCString &s, const KeywordSubstitutionList &keywords)
Definition util.cpp:3418
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:6169
A bunch of utility functions.
bool isId(int c)
Definition util.h:202