Doxygen
Loading...
Searching...
No Matches
rtfgen.cpp
Go to the documentation of this file.
1/******************************************************************************
2 *
3 * Copyright (C) 1997-2023 by Parker Waechter & Dimitri van Heesch.
4 *
5 * Style sheet additions by Alexander Bartolich
6 *
7 * Permission to use, copy, modify, and distribute this software and its
8 * documentation under the terms of the GNU General Public License is hereby
9 * granted. No representations are made about the suitability of this software
10 * for any purpose. It is provided "as is" without express or implied warranty.
11 * See the GNU General Public License for more details.
12 *
13 * Documents produced by Doxygen are derivative works derived from the
14 * input used in their production; they are not affected by this license.
15 *
16 */
17
18#include <mutex>
19#include <stdlib.h>
20#include <algorithm>
21#include <unordered_map>
22
23#include "rtfgen.h"
24#include "config.h"
25#include "message.h"
26#include "doxygen.h"
27#include "util.h"
28#include "diagram.h"
29#include "language.h"
30#include "dot.h"
31#include "dotcallgraph.h"
32#include "dotclassgraph.h"
33#include "dotdirdeps.h"
34#include "dotincldepgraph.h"
35#include "version.h"
36#include "pagedef.h"
37#include "rtfstyle.h"
38#include "rtfdocvisitor.h"
39#include "docparser.h"
40#include "dirdef.h"
41#include "vhdldocgen.h"
42#include "portable.h"
43#include "groupdef.h"
44#include "classlist.h"
45#include "filename.h"
46#include "namespacedef.h"
47#include "dir.h"
48#include "utf8.h"
49#include "debug.h"
50#include "datetime.h"
51#include "outputlist.h"
52#include "moduledef.h"
53
54//#define DBG_RTF(x) x;
55#define DBG_RTF(x)
56
58
60{
61 auto tm = getCurrentDateTime();
62 QCString result;
63 switch (Config_getEnum(TIMESTAMP))
64 {
65 case TIMESTAMP_t::YES:
66 case TIMESTAMP_t::DATETIME:
67 result.sprintf("\\yr%d\\mo%d\\dy%d\\hr%d\\min%d\\sec%d",
68 tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday,
69 tm.tm_hour, tm.tm_min, tm.tm_sec);
70 break;
71 case TIMESTAMP_t::DATE:
72 result.sprintf("\\yr%d\\mo%d\\dy%d",
73 tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday);
74 break;
75 case TIMESTAMP_t::NO:
76 return "";
77 }
78 return "{\\creatim " + result + "}\n";
79}
80
82{
83 QCString result;
84 result.reserve(str.length());
85 if (!str.isEmpty())
86 {
87 const char *p=str.data();
88 while (*p)
89 {
90 char c=*p++;
91
92 switch (c)
93 {
94 case '{': result += "\\{"; break;
95 case '}': result += "\\}"; break;
96 case '\\': result += "\\\\"; break;
97 default: result += c; break;
98 }
99 }
100 }
101 return result;
102}
103
104static QCString makeIndexName(const QCString &s,int i)
105{
106 QCString result=s;
107 result+=static_cast<char>(i+'0');
108 return result;
109}
110
111
112//------------------------------------------------------------------------------------------------
113
117
119 const QCString &ref,const QCString &f,
120 const QCString &anchor,const QCString &name,
121 const QCString &)
122{
123 m_col+=name.length();
124 if (m_hide) return;
125 if (ref.isEmpty() && Config_getBool(RTF_HYPERLINKS))
126 {
127 QCString refName;
128 if (!f.isEmpty())
129 {
130 refName+=stripPath(f);
131 }
132 if (!anchor.isEmpty())
133 {
134 refName+='_';
135 refName+=anchor;
136 }
137
138 *m_t << "{\\field {\\*\\fldinst { HYPERLINK \\\\l \"";
139 *m_t << rtfFormatBmkStr(refName);
140 *m_t << "\" }{}";
141 *m_t << "}{\\fldrslt {\\cs37\\ul\\cf2 ";
142
143 codify(name);
144
145 *m_t << "}}}\n";
146 }
147 else
148 {
149 codify(name);
150 }
151}
152
154{
155 // note that RTF does not have a "verbatim", so "\n" means
156 // nothing... add a "newParagraph()";
157 const int tabSize = Config_getInt(TAB_SIZE);
158 if (!str.isEmpty())
159 {
160 char c;
161 const char *p=str.data();
162 if (m_hide)
163 {
165 }
166 else
167 {
168 while ((c=*p++))
169 {
170 switch(c)
171 {
172 case '\t': {
173 int spacesToNextTabStop = tabSize - (m_col%tabSize);
174 while (spacesToNextTabStop--)
175 {
176 if (m_col>=m_stripIndentAmount) *m_t << " ";
177 m_col++;
178 }
179 }
180 break;
181 case ' ': if (m_col>=m_stripIndentAmount) *m_t << " ";
182 m_col++;
183 break;
184 case '\n': *m_t << "\\par\n";
185 m_col=0;
186 break;
187 case '{': *m_t << "\\{"; m_col++; break;
188 case '}': *m_t << "\\}"; m_col++; break;
189 case '\\': *m_t << "\\\\"; m_col++; break;
190 default: p=writeUTF8Char(*m_t,p-1); m_col++; break;
191 }
192 }
193 }
194 }
195}
196
201
206
208{
209 m_hide = false;
210}
211
213{
214 m_stripIndentAmount = amount;
215}
216
218{
219 DBG_RTF(*m_t << "{\\comment (startCodeFragment) }\n")
220 *m_t << "{\n";
221 *m_t << "\\par\n";
223}
224
226{
227 bool wasHidden = m_hide;
228 m_hide = false;
229 endCodeLine();
230 m_hide = wasHidden;
231
232 DBG_RTF(*m_t << "{\\comment (endCodeFragment) }\n")
233 *m_t << "}\n";
234 //m_omitParagraph = TRUE;
235}
236
237void RTFCodeGenerator::writeLineNumber(const QCString &ref,const QCString &fileName,const QCString &anchor,int l,bool writeLineAnchor)
238{
239 if (m_hide) return;
240 bool rtfHyperlinks = Config_getBool(RTF_HYPERLINKS);
241
242 m_doxyCodeLineOpen = true;
243 if (Config_getBool(SOURCE_BROWSER))
244 {
245 QCString lineNumber;
246 lineNumber.sprintf("%05d",l);
247
248 QCString lineAnchor;
249 if (!m_sourceFileName.isEmpty())
250 {
251 lineAnchor.sprintf("_l%05d",l);
253 }
254 bool showTarget = rtfHyperlinks && !lineAnchor.isEmpty() && writeLineAnchor;
255 if (showTarget)
256 {
257 *m_t << "{\\bkmkstart ";
258 *m_t << rtfFormatBmkStr(lineAnchor);
259 *m_t << "}";
260 *m_t << "{\\bkmkend ";
261 *m_t << rtfFormatBmkStr(lineAnchor);
262 *m_t << "}\n";
263 }
264 if (!fileName.isEmpty())
265 {
266 writeCodeLink(CodeSymbolType::Default,ref,fileName,anchor,lineNumber,QCString());
267 }
268 else
269 {
270 *m_t << lineNumber;
271 }
272 *m_t << " ";
273 }
274 else
275 {
276 *m_t << l << " ";
277 }
278 m_col=0;
279}
280
282{
283 if (m_hide) return;
284 m_doxyCodeLineOpen = true;
285 m_col=0;
286}
287
289{
290 if (m_hide) return;
291 if (m_doxyCodeLineOpen) *m_t << "\\par\n";
292 m_doxyCodeLineOpen = false;
293}
294
296{
297 if (m_hide) return;
298 int cod = 2;
299 static const std::unordered_map<std::string,int> map {
300 { "keyword", 17 },
301 { "keywordtype", 18 },
302 { "keywordflow", 19 },
303 { "comment", 20 },
304 { "preprocessor", 21 },
305 { "stringliteral", 22 },
306 { "charliteral", 23 },
307 { "vhdldigit", 24 },
308 { "vhdlchar", 25 },
309 { "vhdlkeyword", 26 },
310 { "vhdllogic", 27 }
311 };
312 auto it = map.find(name.str());
313 if (it != map.end())
314 {
315 cod = it->second;
316 }
317 *m_t << "{\\cf" << cod << " ";
318}
319
321{
322 if (m_hide) return;
323 *m_t << "}";
324}
325
327{
328 QCString n=makeIndexName("CodeExample",m_indentLevel);
329 return rtf_Style[n.str()].reference();
330}
331
333{
334 m_sourceFileName = name;
335}
336
337//------------------------------------------------------------------------------------------------
338
340 : OutputGenerator(Config_getString(RTF_OUTPUT))
341 , m_codeList(std::make_unique<OutputCodeList>())
342{
344}
345
358
360{
361 if (this!=&og)
362 {
363 m_dir = og.m_dir;
364 m_codeList = std::make_unique<OutputCodeList>(*og.m_codeList);
366 m_codeGen->setTextStream(&m_t);
369 m_numCols = og.m_numCols;
370 m_relPath = og.m_relPath;
373 }
374 return *this;
375}
376
378
383
385{
386 m_relPath = path;
387}
388
390{
391 m_codeGen->setSourceFileName(name);
392}
393
395{
396 t << "# Generated by doxygen " << getDoxygenVersion() << "\n\n";
397 t << "# This file describes styles used for generating RTF output.\n";
398 t << "# All text after a hash (#) is considered a comment and will be ignored.\n";
399 t << "# Remove a hash to activate a line.\n\n";
400
401 for (int i=0 ; rtf_Style_Default[i].reference!=nullptr ; i++ )
402 {
403 t << "# " << rtf_Style_Default[i].name << " = "
404 << rtf_Style_Default[i].reference
405 << rtf_Style_Default[i].definition << "\n";
406 }
407}
408
410{
411 t << "# Generated by doxygen " << getDoxygenVersion() << "\n\n";
412 t << "# This file describes extensions used for generating RTF output.\n";
413 t << "# All text after a hash (#) is considered a comment and will be ignored.\n";
414 t << "# Remove a hash to activate a line.\n\n";
415
416 t << "# Overrides the project title.\n";
417
418 t << "#Title = \n\n";
419
420 t << "# Name of the company that produced this document.\n";
421 t << "#Company = \n\n";
422
423 t << "# Filename of a company or project logo.\n";
424 t << "#LogoFilename = \n\n";
425
426 t << "# Author of the document.\n";
427 t << "#Author = \n\n";
428
429 t << "# Type of document (e.g. Design Specification, User Manual, etc.).\n";
430 t << "#DocumentType = \n\n";
431
432 t << "# Document tracking number.\n";
433 t << "#DocumentId = \n\n";
434
435 t << "# Name of the author's manager.\n";
436 t << "# This field is not displayed in the document itself, but it is \n";
437 t << "# available in the information block of the rtf file. In Microsoft \n";
438 t << "# Word, it is available under File:Properties.\n";
439 t << "#Manager = \n\n";
440
441 t << "# Subject of the document.\n";
442 t << "# This field is not displayed in the document itself, but it is \n";
443 t << "# available in the information block of the rtf file. In Microsoft \n";
444 t << "# Word, it is available under File:Properties.\n";
445 t << "#Subject = \n\n";
446
447 t << "# Comments regarding the document.\n";
448 t << "# This field is not displayed in the document itself, but it is \n";
449 t << "# available in the information block of the rtf file. In Microsoft \n";
450 t << "# Word, it is available under File:Properties.\n";
451 t << "#Comments = \n\n";
452
453 t << "# Keywords associated with the document.\n";
454 t << "# This field is not displayed in the document itself, but it is \n";
455 t << "# available in the information block of the rtf file. In Microsoft \n";
456 t << "# Word, it is available under File:Properties.\n";
457 t << "#Keywords = \n\n";
458}
459
460
462{
463 QCString dir=Config_getString(RTF_OUTPUT);
464 Dir d(dir.str());
465 if (!d.exists() && !d.mkdir(dir.str()))
466 {
467 term("Could not create output directory {}\n",dir);
468 }
469
470 // first duplicate strings of rtf_Style_Default
471 const struct Rtf_Style_Default* def = rtf_Style_Default;
472 while (def->reference)
473 {
474 if (def->definition == nullptr)
475 {
476 err("Internal: rtf_Style_Default[{}] has no definition.\n", def->name);
477 }
478 else
479 {
480 rtf_Style.emplace(def->name, StyleData(def->reference, def->definition));
481 }
482 def++;
483 }
484
485 // overwrite some (or all) definitions from file
486 QCString rtfStyleSheetFile = Config_getString(RTF_STYLESHEET_FILE);
487 if (!rtfStyleSheetFile.isEmpty())
488 {
489 loadStylesheet(rtfStyleSheetFile, rtf_Style);
490 }
491
492 // If user has defined an extension file, load its contents.
493 QCString rtfExtensionsFile = Config_getString(RTF_EXTENSIONS_FILE);
494 if (!rtfExtensionsFile.isEmpty())
495 {
496 loadExtensions(rtfExtensionsFile);
497
498 if (!rtf_logoFilename.isEmpty())
499 {
500 FileInfo fi(rtf_logoFilename.str());
501 if (!fi.exists())
502 {
503 err("Logo '{}' specified by 'LogoFilename' in the rtf extension file '{}' does not exist!\n",
504 rtf_logoFilename, rtfExtensionsFile);
505 rtf_logoFilename = "";
506 }
507 else
508 {
509 QCString destFileName = Config_getString(RTF_OUTPUT)+"/"+fi.fileName();
510 copyFile(rtf_logoFilename,destFileName);
512 }
513 }
514 }
515
516 createSubDirs(d);
517}
518
520{
521 QCString dname = Config_getString(RTF_OUTPUT);
522 Dir d(dname.str());
523 clearSubDirs(d);
524}
525
527{
528 /* all the included RTF files should begin with the
529 * same header
530 */
531 m_t << "{\\rtf1\\ansi\\ansicpg" << theTranslator->trRTFansicp();
532 m_t << "\\uc1 \\deff0\\deflang1033\\deflangfe1033\n";
533
534 DBG_RTF(m_t << "{\\comment Beginning font list}\n")
535 m_t << "{\\fonttbl ";
536 m_t << "{\\f0\\froman\\fcharset" << theTranslator->trRTFCharSet();
537 m_t << "\\fprq2{\\*\\panose 02020603050405020304}Times New Roman;}\n";
538 m_t << "{\\f1\\fswiss\\fcharset" << theTranslator->trRTFCharSet();
539 m_t << "\\fprq2{\\*\\panose 020b0604020202020204}Arial;}\n";
540 m_t << "{\\f2\\fmodern\\fcharset" << theTranslator->trRTFCharSet();
541 m_t << "\\fprq1{\\*\\panose 02070309020205020404}Courier New;}\n";
542 m_t << "{\\f3\\froman\\fcharset2\\fprq2{\\*\\panose 05050102010706020507}Symbol;}\n";
543 m_t << "}\n";
544 DBG_RTF(m_t << "{\\comment begin colors}\n")
545 m_t << "{\\colortbl;";
546 m_t << "\\red0\\green0\\blue0;";
547 m_t << "\\red0\\green0\\blue255;";
548 m_t << "\\red0\\green255\\blue255;";
549 m_t << "\\red0\\green255\\blue0;";
550 m_t << "\\red255\\green0\\blue255;";
551 m_t << "\\red255\\green0\\blue0;";
552 m_t << "\\red255\\green255\\blue0;";
553 m_t << "\\red255\\green255\\blue255;";
554 m_t << "\\red0\\green0\\blue128;";
555 m_t << "\\red0\\green128\\blue128;";
556 m_t << "\\red0\\green128\\blue0;";
557 m_t << "\\red128\\green0\\blue128;";
558 m_t << "\\red128\\green0\\blue0;";
559 m_t << "\\red128\\green128\\blue0;";
560 m_t << "\\red128\\green128\\blue128;";
561 m_t << "\\red192\\green192\\blue192;";
562
563 // code highlighting colors. Note order is important see also RTFGenerator::startFontClass
564 m_t << "\\red0\\green128\\blue0;"; // keyword = index 17
565 m_t << "\\red96\\green64\\blue32;"; // keywordtype
566 m_t << "\\rede0\\green128\\blue0;"; // keywordflow
567 m_t << "\\red128\\green0\\blue0;"; // comment
568 m_t << "\\red128\\green96\\blue32;"; // preprocessor
569 m_t << "\\red0\\green32\\blue128;"; // stringliteral
570 m_t << "\\red0\\green128\\blue128;"; // charliteral
571 m_t << "\\red255\\green0\\blue255;"; // vhdldigit
572 m_t << "\\red0\\green0\\blue0;"; // vhdlchar
573 m_t << "\\red112\\green0\\blue112;"; // vhdlkeyword
574 m_t << "\\red255\\green0\\blue0;"; // vhdllogic
575
576 m_t << "}\n";
577
578 DBG_RTF(m_t << "{\\comment Beginning style list}\n")
579 m_t << "{\\stylesheet\n";
580 m_t << "{\\widctlpar\\adjustright \\fs20\\cgrid \\snext0 Normal;}\n";
581
582 // set the paper dimensions according to PAPER_TYPE
583 auto paperType = Config_getEnum(PAPER_TYPE);
584 m_t << "{";
585 switch (paperType)
586 {
587 // width & height values are inches * 1440
588 case PAPER_TYPE_t::a4: m_t << "\\paperw11900\\paperh16840"; break;
589 case PAPER_TYPE_t::letter: m_t << "\\paperw12240\\paperh15840"; break;
590 case PAPER_TYPE_t::legal: m_t << "\\paperw12240\\paperh20160"; break;
591 case PAPER_TYPE_t::executive: m_t << "\\paperw10440\\paperh15120"; break;
592 }
593 m_t << "\\margl1800\\margr1800\\margt1440\\margb1440\\gutter0\\ltrsect}\n";
594
595 // sort styles ascending by \s-number via an intermediate QArray
596 unsigned maxIndex = 0;
597 for (const auto &[name,data] : rtf_Style)
598 {
599 uint32_t index = data.index();
600 if (index > maxIndex) maxIndex = index;
601 }
602 std::vector<const StyleData*> array(maxIndex + 1, nullptr);
603 ASSERT(maxIndex < array.size());
604
605 for (const auto &[name,data] : rtf_Style)
606 {
607 uint32_t index = data.index();
608 if (array[index] != nullptr)
609 {
610 err("Style '{}' redefines \\s{}.\n", name, index);
611 }
612 array[index] = &data;
613 }
614
615 // write array elements
616 size_t size = array.size();
617 for(size_t i = 0; i < size; i++)
618 {
619 const StyleData *pStyle = array[i];
620 if (pStyle)
621 {
622 m_t << "{" << pStyle->reference() << pStyle->definition() << ";}\n";
623 }
624 }
625
626 m_t << "}\n";
627
628 // place to write rtf_Table_Default
629 int id = -1;
630 m_t << "{\\*\\listtable" << "\n";
631 for (int i=0 ; rtf_Table_Default[i].definition ; i++ )
632 {
633 if (id != rtf_Table_Default[i].id)
634 {
635 if (id != -1)
636 {
637 m_t << "\\listid" << id << "}" << "\n";
638 }
639 id = rtf_Table_Default[i].id;
640 m_t << "{\\list\\listtemplateid" << rtf_Table_Default[i].id << "\n";
641 }
642 m_t << "{ " << rtf_Table_Default[i].definition << " }" << "\n";
643 }
644 m_t << "\\listid" << id << "}" << "\n";
645 m_t << "}" <<"\n";
646 m_t << "{\\listoverridetable" <<"\n";
647 id = -1;
648 for (int i=0 ; rtf_Table_Default[i].definition ; i++ )
649 {
650 if (id != rtf_Table_Default[i].id)
651 {
652 id = rtf_Table_Default[i].id;
653 m_t << "{\\listoverride\\listid" << id << "\\listoverridecount0\\ls" << id << "}" << "\n";
654 }
655 }
656 m_t << "}" << "\n";
657
658 // this comment is needed for postprocessing!
659 m_t << "{\\comment begin body}\n";
660
661}
662
664{
665 m_t << "\n";
666 DBG_RTF(m_t << "{\\comment BeginRTFChapter}\n")
668
669 // if we are compact, no extra page breaks...
670 if (Config_getBool(COMPACT_RTF))
671 {
672 // m_t << "\\sect\\sectd\\sbknone\n";
673 m_t << "\\sect\\sbknone\n";
675 }
676 else
677 m_t << "\\sect\\sbkpage\n";
678 //m_t << "\\sect\\sectd\\sbkpage\n";
679
680 m_t << rtf_Style["Heading1"].reference() << "\n";
681}
682
684{
685 m_t << "\n";
686 DBG_RTF(m_t << "{\\comment BeginRTFSection}\n")
688
689 // if we are compact, no extra page breaks...
690 if (Config_getBool(COMPACT_RTF))
691 {
692 m_t << "\\sect\\sbknone\n";
694 }
695 else
696 {
697 m_t << "\\sect\\sbkpage\n";
698 }
699 int level = 2 + m_hierarchyLevel;
700
701 m_t << rtf_Style[QCString().sprintf("Heading%d", level).str()].reference() << "\n";
702}
703
704void RTFGenerator::startFile(const QCString &name,const QCString &,const QCString &,int,int hierarchyLevel)
705{
706 //setEncoding(QCString().sprintf("CP%s",theTranslator->trRTFansicp()));
707 QCString fileName=name;
709 m_hierarchyLevel = hierarchyLevel;
710
711 if (!fileName.endsWith(".rtf")) fileName+=".rtf";
716}
717
719{
720 DBG_RTF(m_t << "{\\comment endFile}\n")
721 m_t << "}";
722
723 endPlainFile();
725}
726
728{
729 DBG_RTF(m_t << "{\\comment startProjectNumber }\n")
730 m_t << " ";
731}
732
734{
735 DBG_RTF(m_t << "{\\comment endProjectNumber }\n")
736}
737
739{
740 //QCString paperName;
741
742 //m_indentLevel = 0;
743
744 switch (is)
745 {
747 // basic RTFstart
748 // get readyfor author etc
749
750 m_t << "{\\info \n";
751 m_t << "{\\title {\\comment ";
752 break;
754 m_t << "}\n";
755 if (!rtf_subject.isEmpty()) m_t << "{\\subject " << rtf_subject << "}\n";
756 if (!rtf_comments.isEmpty()) m_t << "{\\comment " << rtf_comments << "}\n";
757 if (!rtf_company.isEmpty()) m_t << "{\\company " << rtf_company << "}\n";
758 if (!rtf_author.isEmpty()) m_t << "{\\author " << rtf_author << "}\n";
759 if (!rtf_manager.isEmpty()) m_t << "{\\manager " << rtf_manager << "}\n";
760 if (!rtf_documentType.isEmpty()) m_t << "{\\category " << rtf_documentType << "}\n";
761 if (!rtf_keywords.isEmpty()) m_t << "{\\keywords " << rtf_keywords << "}\n";
762 m_t << "{\\comment ";
763 break;
765 //Introduction
767 break;
769 //Topic Index
771 break;
773 //Module Index
775 break;
777 //Directory Index
779 break;
781 //Namespace Index
783 break;
785 //Concept Index
787 break;
789 //Hierarchical Index
790 DBG_RTF(m_t << "{\\comment start classhierarchy}\n")
792 break;
794 //Annotated Compound Index
796 break;
798 //Annotated File Index
800 break;
802 //Related Page Index
804 break;
806 {
807 //Topic Documentation
808 for (const auto &gd : *Doxygen::groupLinkedMap)
809 {
810 if (!gd->isReference())
811 {
813 break;
814 }
815 }
816 }
817 break;
819 {
820 //Module Documentation
821 for (const auto &mod : ModuleManager::instance().modules())
822 {
823 if (!mod->isReference() && mod->isPrimaryInterface())
824 {
826 break;
827 }
828 }
829 }
830 break;
832 {
833 //Directory Documentation
834 for (const auto &dd : *Doxygen::dirLinkedMap)
835 {
836 if (dd->isLinkableInProject())
837 {
839 break;
840 }
841 }
842 }
843 break;
845 {
846 // Namespace Documentation
847 for (const auto &nd : *Doxygen::namespaceLinkedMap)
848 {
849 if (nd->isLinkableInProject())
850 {
852 break;
853 }
854 }
855 }
856 break;
858 {
859 // Concept Documentation
860 for (const auto &cd : *Doxygen::conceptLinkedMap)
861 {
862 if (cd->isLinkableInProject())
863 {
865 break;
866 }
867 }
868 }
869 break;
871 {
872 //Compound Documentation
873 for (const auto &cd : *Doxygen::classLinkedMap)
874 {
875 if (cd->isLinkableInProject() &&
876 !cd->isImplicitTemplateInstance() &&
877 !cd->isEmbeddedInOuterScope() &&
878 !cd->isAlias()
879 )
880 {
882 break;
883 }
884 }
885 }
886 break;
888 {
889 //File Documentation
890 bool isFirst=TRUE;
891 for (const auto &fn : *Doxygen::inputNameLinkedMap)
892 {
893 for (const auto &fd : *fn)
894 {
895 if (fd->isLinkableInProject() || fd->generateSourceFile())
896 {
897 if (isFirst)
898 {
900 isFirst=FALSE;
901 break;
902 }
903 }
904 }
905 if (!isFirst)
906 {
907 break;
908 }
909 }
910 }
911 break;
913 {
914 //Example Documentation
916 }
917 break;
919 break;
921 break;
923 break;
924 }
925}
926
928{
929 bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN);
930 bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL);
931 QCString projectName = Config_getString(PROJECT_NAME);
932
933 switch (is)
934 {
936 if (!rtf_title.isEmpty())
937 // User has overridden document title in extensions file
938 m_t << "}" << rtf_title;
939 else
940 m_t << "}" << projectName;
941 break;
943 {
944 m_t << " doxygen " << getDoxygenVersion() << ".}\n";
946 DBG_RTF(m_t << "{\\comment end of infoblock}\n");
947 // setup for this section
948 m_t << "}";
949 m_t << rtf_Style_Reset <<"\n";
950 m_t << "\\sectd\\pgnlcrm\n";
951 m_t << "{\\footer "<<rtf_Style["Footer"].reference() << "{\\chpgn}}\n";
952 // the title entry
953 DBG_RTF(m_t << "{\\comment begin title page}\n")
954
955
956 m_t << rtf_Style_Reset << rtf_Style["SubTitle"].reference() << "\n"; // set to title style
957
958 m_t << "\\vertalc\\qc\\par\\par\\par\\par\\par\\par\\par\n";
959 if (!rtf_logoFilename.isEmpty())
960 {
961 m_t << "{\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"" << rtf_logoFilename;
962 m_t << "\" \\\\d \\\\*MERGEFORMAT} {\\fldrslt IMAGE }}\\par\\par\n";
963 }
964 if (!rtf_company.isEmpty())
965 {
966 m_t << rtf_company << "\\par\\par\n";
967 }
968
969 m_t << rtf_Style_Reset << rtf_Style["Title"].reference() << "\n"; // set to title style
970 if (!rtf_title.isEmpty())
971 {
972 // User has overridden document title in extensions file
973 m_t << "{\\field\\fldedit {\\*\\fldinst TITLE \\\\*MERGEFORMAT}{\\fldrslt " << rtf_title << "}}\\par\n";
974 }
975 else
976 {
977 auto parser { createDocParser() };
978 auto ast { validatingParseText(*parser.get(), projectName) };
979 if (ast)
980 {
981 m_t << "{\\field\\fldedit {\\*\\fldinst TITLE \\\\*MERGEFORMAT}{\\fldrslt ";
982 writeDoc(ast.get(),nullptr,nullptr,0);
983 m_t << "}}\\par\n";
984 }
985 }
986
987 m_t << rtf_Style_Reset << rtf_Style["SubTitle"].reference() << "\n"; // set to title style
988 m_t << "\\par\n";
989 if (!rtf_documentType.isEmpty())
990 {
991 m_t << rtf_documentType << "\\par\n";
992 }
993 if (!rtf_documentId.isEmpty())
994 {
995 m_t << rtf_documentId << "\\par\n";
996 }
997 m_t << "\\par\\par\\par\\par\\par\\par\\par\\par\\par\\par\\par\\par\n";
998
999 m_t << rtf_Style_Reset << rtf_Style["SubTitle"].reference() << "\n"; // set to subtitle style
1000 if (!rtf_author.isEmpty())
1001 {
1002 m_t << "{\\field\\fldedit {\\*\\fldinst AUTHOR \\\\*MERGEFORMAT}{\\fldrslt "<< rtf_author << " }}\\par\n";
1003 }
1004 else
1005 {
1006 m_t << "{\\field\\fldedit {\\*\\fldinst AUTHOR \\\\*MERGEFORMAT}{\\fldrslt AUTHOR}}\\par\n";
1007 }
1008
1009 m_t << theTranslator->trVersion() << " " << Config_getString(PROJECT_NUMBER) << "\\par";
1010 switch (Config_getEnum(TIMESTAMP))
1011 {
1012 case TIMESTAMP_t::YES:
1013 case TIMESTAMP_t::DATETIME:
1014 m_t << "{\\field\\fldedit {\\*\\fldinst CREATEDATE \\\\*MERGEFORMAT}"
1015 "{\\fldrslt "<< dateToString(DateTimeType::DateTime) << " }}\\par\n";
1016 break;
1017 case TIMESTAMP_t::DATE:
1018 m_t << "{\\field\\fldedit {\\*\\fldinst CREATEDATE \\\\*MERGEFORMAT}"
1019 "{\\fldrslt "<< dateToString(DateTimeType::Date) << " }}\\par\n";
1020 break;
1021 case TIMESTAMP_t::NO:
1022 break;
1023 }
1024 m_t << "\\page\\page";
1025 DBG_RTF(m_t << "{\\comment End title page}\n")
1026
1027 // table of contents section
1028 DBG_RTF(m_t << "{\\comment Table of contents}\n")
1029 m_t << "\\vertalt\n";
1030 m_t << rtf_Style_Reset << "\n";
1031 m_t << rtf_Style["Heading1"].reference();
1032 m_t << theTranslator->trRTFTableOfContents() << "\\par\n";
1033 m_t << rtf_Style_Reset << "\\par\n";
1034 m_t << "{\\field\\fldedit {\\*\\fldinst TOC \\\\f \\\\*MERGEFORMAT}{\\fldrslt Table of contents}}\\par\n";
1035 m_t << rtf_Style_Reset << "\n";
1036 }
1037 break;
1040 {
1041 writePageLink(Doxygen::mainPage->getOutputFileBase(), TRUE);
1042 }
1043 break;
1045 m_t << "\\par " << rtf_Style_Reset << "\n";
1046 m_t << "{\\tc \\v " << theTranslator->trTopicIndex() << "}\n";
1047 m_t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"topics.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
1048 break;
1050 m_t << "\\par " << rtf_Style_Reset << "\n";
1051 m_t << "{\\tc \\v " << theTranslator->trModuleIndex() << "}\n";
1052 m_t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"modules.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
1053 break;
1055 m_t << "\\par " << rtf_Style_Reset << "\n";
1056 m_t << "{\\tc \\v " << theTranslator->trDirIndex() << "}\n";
1057 m_t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"dirs.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
1058 break;
1060 m_t << "\\par " << rtf_Style_Reset << "\n";
1061 if (fortranOpt)
1062 {
1063 m_t << "{\\tc \\v " << theTranslator->trModulesIndex() << "}\n";
1064 }
1065 else
1066 {
1067 m_t << "{\\tc \\v " << theTranslator->trNamespaceIndex() << "}\n";
1068 }
1069
1070 m_t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"namespaces.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
1071 break;
1073 m_t << "\\par " << rtf_Style_Reset << "\n";
1074 m_t << "{\\tc \\v " << theTranslator->trConceptIndex() << "}\n";
1075 m_t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"concepts.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
1076 break;
1078 m_t << "\\par " << rtf_Style_Reset << "\n";
1079 m_t << "{\\tc \\v " << theTranslator->trHierarchicalIndex() << "}\n";
1080 m_t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"hierarchy.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
1081 break;
1083 m_t << "\\par " << rtf_Style_Reset << "\n";
1084 if (fortranOpt)
1085 {
1086 m_t << "{\\tc \\v " << theTranslator->trCompoundIndexFortran() << "}\n";
1087 }
1088 else if (vhdlOpt)
1089 {
1090 m_t << "{\\tc \\v " << theTranslator->trDesignUnitIndex() << "}\n";
1091 }
1092 else
1093 {
1094 m_t << "{\\tc \\v " << theTranslator->trCompoundIndex() << "}\n";
1095 }
1096 m_t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"annotated.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
1097 break;
1099 m_t << "\\par " << rtf_Style_Reset << "\n";
1100 m_t << "{\\tc \\v " << theTranslator->trFileIndex() << "}\n";
1101 m_t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"files.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
1102 break;
1104 m_t << "\\par " << rtf_Style_Reset << "\n";
1105 m_t << "{\\tc \\v " << theTranslator->trPageIndex() << "}\n";
1106 m_t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"pages.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
1107 break;
1109 {
1110 m_t << "{\\tc \\v " << theTranslator->trTopicDocumentation() << "}\n";
1111 for (const auto &gd : *Doxygen::groupLinkedMap)
1112 {
1113 if (!gd->isReference() && !gd->isASubGroup())
1114 {
1115 writePageLink(gd->getOutputFileBase(), FALSE);
1116 }
1117 }
1118 }
1119 break;
1121 {
1122 m_t << "{\\tc \\v " << theTranslator->trModuleDocumentation() << "}\n";
1123 for (const auto &mod : ModuleManager::instance().modules())
1124 {
1125 if (!mod->isReference() && mod->isPrimaryInterface())
1126 {
1127 writePageLink(mod->getOutputFileBase(), FALSE);
1128 }
1129 }
1130 }
1131 break;
1133 {
1134 bool first=true;
1135 m_t << "{\\tc \\v " << theTranslator->trDirDocumentation() << "}\n";
1136 for (const auto &dd : *Doxygen::dirLinkedMap)
1137 {
1138 if (dd->isLinkableInProject())
1139 {
1140 m_t << "\\par " << rtf_Style_Reset << "\n";
1141 if (!first)
1142 {
1144 }
1145 first=false;
1146 m_t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
1147 m_t << dd->getOutputFileBase();
1148 m_t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
1149 }
1150 }
1151 }
1152 break;
1154 {
1155 bool first=true;
1156 for (const auto &nd : *Doxygen::namespaceLinkedMap)
1157 {
1158 if (nd->isLinkableInProject() && !nd->isAlias())
1159 {
1160 m_t << "\\par " << rtf_Style_Reset << "\n";
1161 if (!first)
1162 {
1164 }
1165 first=false;
1166 m_t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
1167 m_t << nd->getOutputFileBase();
1168 m_t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
1169 }
1170 }
1171 }
1172 break;
1174 {
1175 bool first=true;
1176 for (const auto &cd : *Doxygen::conceptLinkedMap)
1177 {
1178 if (cd->isLinkableInProject() && !cd->isAlias())
1179 {
1180 m_t << "\\par " << rtf_Style_Reset << "\n";
1181 if (!first)
1182 {
1184 }
1185 first=false;
1186 m_t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
1187 m_t << cd->getOutputFileBase();
1188 m_t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
1189 }
1190 }
1191 }
1192 break;
1194 {
1195 bool first=true;
1196 if (fortranOpt)
1197 {
1198 m_t << "{\\tc \\v " << theTranslator->trTypeDocumentation() << "}\n";
1199 }
1200 else
1201 {
1202 m_t << "{\\tc \\v " << theTranslator->trClassDocumentation() << "}\n";
1203 }
1204 for (const auto &cd : *Doxygen::classLinkedMap)
1205 {
1206 if (cd->isLinkableInProject() &&
1207 !cd->isImplicitTemplateInstance() &&
1208 !cd->isEmbeddedInOuterScope() &&
1209 !cd->isAlias()
1210 )
1211 {
1212 m_t << "\\par " << rtf_Style_Reset << "\n";
1213 if (!first)
1214 {
1216 }
1217 first=false;
1218 m_t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
1219 m_t << cd->getOutputFileBase();
1220 m_t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
1221 }
1222 }
1223 }
1224 break;
1226 {
1227 bool isFirst=TRUE;
1228
1229 m_t << "{\\tc \\v " << theTranslator->trFileDocumentation() << "}\n";
1230 for (const auto &fn : *Doxygen::inputNameLinkedMap)
1231 {
1232 for (const auto &fd : *fn)
1233 {
1234 if (fd->isLinkableInProject())
1235 {
1236 m_t << "\\par " << rtf_Style_Reset << "\n";
1237 if (!isFirst)
1238 {
1240 }
1241 isFirst=FALSE;
1242 m_t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
1243 m_t << fd->getOutputFileBase();
1244 m_t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
1245 }
1246 if (fd->generateSourceFile())
1247 {
1248 m_t << "\\par " << rtf_Style_Reset << "\n";
1249 if (!isFirst)
1250 {
1252 }
1253 isFirst=FALSE;
1254 m_t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
1255 m_t << fd->getSourceFileBase();
1256 m_t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
1257 }
1258 }
1259 }
1260 }
1261 break;
1263 {
1264 //m_t << "}\n";
1265 bool isFirst=true;
1266 m_t << "{\\tc \\v " << theTranslator->trExamples() << "}\n";
1267 for (const auto &pd : *Doxygen::exampleLinkedMap)
1268 {
1269 m_t << "\\par " << rtf_Style_Reset << "\n";
1270 if (!isFirst)
1271 {
1273 }
1274 isFirst=false;
1275 m_t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
1276 m_t << pd->getOutputFileBase();
1277 m_t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
1278 }
1279 }
1280 break;
1282 {
1283 m_t << "\\par " << rtf_Style_Reset << "\n";
1284 for (const auto &pd : *Doxygen::pageLinkedMap)
1285 {
1286 if (!pd->getGroupDef() && !pd->isReference() && !pd->hasParentPage()
1287 && Doxygen::mainPage.get() != pd.get())
1288 {
1289 writePageLink(pd->getOutputFileBase(), FALSE);
1290 }
1291 }
1292 }
1293 break;
1295 break;
1298 m_t << rtf_Style["Heading1"].reference();
1299 m_t << theTranslator->trRTFGeneralIndex() << "\\par \n";
1300 m_t << rtf_Style_Reset << "\n";
1301 m_t << "{\\tc \\v " << theTranslator->trRTFGeneralIndex() << "}\n";
1302 m_t << "{\\field\\fldedit {\\*\\fldinst INDEX \\\\c2 \\\\*MERGEFORMAT}{\\fldrslt INDEX}}\n";
1303
1304 break;
1305 }
1306}
1307
1309{
1310 m_t << "\\par " << rtf_Style_Reset << "\n";
1311 m_t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
1312 m_t << name;
1313 m_t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
1314}
1315
1317{
1318 DBG_RTF(m_t << "{\\comment Beginning Body of RTF Document}\n")
1319 // end page and setup for rest of document
1320 m_t << "\\sect \\sbkpage \\pgndec \\pgnrestart\n";
1321 m_t << "\\sect \\sectd \\sbknone\n";
1322
1323 // set new footer with arabic numbers
1324 m_t << "{\\footer "<< rtf_Style["Footer"].reference() << "{\\chpgn}}\n";
1325
1326}
1327
1329{
1330}
1331
1333{
1334 DBG_RTF(m_t << "{\\comment (lineBreak)}" << "\n")
1335 m_t << "\\par\n";
1337}
1338
1340{
1341 m_t << text;
1342}
1343
1345{
1346 DBG_RTF(m_t << "{\\comment (startIndexList)}\n")
1347 m_t << "{\n";
1348 m_t << "\\par\n";
1352}
1353
1355{
1356 DBG_RTF(m_t << "{\\comment (endIndexList)}\n")
1357 if (!m_omitParagraph)
1358 {
1359 m_t << "\\par";
1361 }
1362 m_t << "}";
1364}
1365
1366/*! start bullet list */
1368{
1369 newParagraph();
1371 int level = indentLevel();
1372 DBG_RTF(m_t << "{\\comment (startItemList level=" << level << ") }\n")
1373 m_t << "{";
1374 m_listItemInfo[level].number = 1;
1375 m_listItemInfo[level].isEnum = false;
1376 m_listItemInfo[level].type = '1';
1377}
1378
1379/*! end bullet list */
1381{
1382 newParagraph();
1383 DBG_RTF(m_t << "{\\comment (endItemList level=" << indentLevel() << ")}\n")
1384 m_t << "}";
1387}
1388
1389/*! write bullet or enum item */
1391{
1392 DBG_RTF(m_t << "{\\comment (startItemListItem)}\n")
1393 newParagraph();
1395 int level = indentLevel();
1396 if (m_listItemInfo[level].isEnum)
1397 {
1398 m_t << rtf_EList_DepthStyle() << "\n";
1399 m_t << m_listItemInfo[level].number << ".\\tab ";
1400 m_listItemInfo[level].number++;
1401 }
1402 else
1403 {
1404 m_t << rtf_BList_DepthStyle() << "\n";
1405 }
1407}
1408
1410{
1411 DBG_RTF(m_t << "{\\comment (endItemListItem)}\n")
1412}
1413
1415{
1416 DBG_RTF(m_t << "{\\comment (startIndexItem)}\n")
1417
1418 if (!m_omitParagraph)
1419 {
1420 m_t << "\\par\n";
1422 }
1423}
1424
1426{
1427 DBG_RTF(m_t << "{\\comment (endIndexItem)}\n")
1428 if (ref.isEmpty() && !fn.isEmpty())
1429 {
1430 m_t << "\\tab ";
1432 m_t << "\n";
1433 }
1434 else
1435 {
1436 m_t << "\n";
1437 }
1439}
1440
1442 const QCString &path,const QCString &name)
1443{
1444 DBG_RTF(m_t << "{\\comment (writeStartAnnoItem)}\n")
1445 m_t << "{\\b ";
1446 if (!path.isEmpty()) docify(path);
1447 if (!f.isEmpty() && Config_getBool(RTF_HYPERLINKS))
1448 {
1449 m_t << "{\\field {\\*\\fldinst { HYPERLINK \\\\l \"";
1451 m_t << "\" }{}";
1452 m_t << "}{\\fldrslt {\\cs37\\ul\\cf2 ";
1453
1454 docify(name);
1455
1456 m_t << "}}}\n";
1457 }
1458 else
1459 {
1460 docify(name);
1461 }
1462 m_t << "} ";
1463}
1464
1466{
1467 DBG_RTF(m_t << "{\\comment (startIndexKey)}\n")
1468 m_t << "{\\b ";
1469}
1470
1472{
1473 DBG_RTF(m_t << "{\\comment (endIndexKey)}\n")
1474}
1475
1477{
1478 DBG_RTF(m_t << "{\\comment (startIndexValue)}\n")
1479 m_t << " ";
1480 if (hasBrief) m_t << "(";
1481}
1482
1484{
1485 DBG_RTF(m_t << "{\\comment (endIndexValue)}\n")
1486 if (hasBrief) m_t << ")";
1487 m_t << "} ";
1488 if (!name.isEmpty())
1489 {
1490 m_t << "\\tab ";
1491 writeRTFReference(name);
1492 m_t << "\n";
1493 }
1494 else
1495 {
1496 m_t << "\n";
1497 }
1499 newParagraph();
1500}
1501
1503{
1504 //beginRTFSubSubSection();
1505 m_t << "\n";
1506 DBG_RTF(m_t << "{\\comment Begin SubSubSection}\n")
1507 m_t << "{\n";
1508 int level = 4 + m_hierarchyLevel;
1509 m_t << rtf_Style_Reset << rtf_Style[QCString().sprintf("Heading%d", level).str()].reference() << "\n";
1510}
1511
1513{
1514 newParagraph();
1515 m_t << "}\n";
1516}
1517
1519{
1520 if (Config_getBool(RTF_HYPERLINKS))
1521 {
1522 QCString ref;
1523 if (!f.isEmpty())
1524 {
1525 ref+=stripPath(f);
1526 }
1527 if (!anchor.isEmpty())
1528 {
1529 ref+='_';
1530 ref+=anchor;
1531 }
1532
1533 m_t << "{\\field {\\*\\fldinst { HYPERLINK \\\\l \"";
1534 m_t << rtfFormatBmkStr(ref);
1535 m_t << "\" }{}";
1536 m_t << "}{\\fldrslt {\\cs37\\ul\\cf2 ";
1537 }
1538}
1539
1541{
1542 if (Config_getBool(RTF_HYPERLINKS))
1543 {
1544 m_t << "}}}\n";
1545 }
1546}
1547
1548static QCString objectLinkToString(const QCString &ref, const QCString &f,
1549 const QCString &anchor, const QCString &text)
1550{
1551 QCString result;
1552 if (ref.isEmpty() && Config_getBool(RTF_HYPERLINKS))
1553 {
1554 QCString refName;
1555 if (!f.isEmpty())
1556 {
1557 refName+=stripPath(f);
1558 }
1559 if (!anchor.isEmpty())
1560 {
1561 refName+='_';
1562 refName+=anchor;
1563 }
1564
1565 result += "{\\field {\\*\\fldinst { HYPERLINK \\\\l \"";
1566 result += rtfFormatBmkStr(refName);
1567 result += "\" }{}";
1568 result += "}{\\fldrslt {\\cs37\\ul\\cf2 ";
1569
1570 result += docifyToString(text);
1571
1572 result += "}}}\n";
1573 }
1574 else
1575 {
1576 result += "{\\b ";
1577 result += docifyToString(text);
1578 result += "}";
1579 }
1580 return result;
1581}
1582
1584 const QCString &anchor, const QCString &text)
1585{
1586 m_t << objectLinkToString(ref,f,anchor,text);
1587}
1588
1590{
1591 m_t << " (";
1592 startEmphasis();
1593}
1594
1595void RTFGenerator::endPageRef(const QCString &clname, const QCString &anchor)
1596{
1597 QCString ref;
1598 if (!clname.isEmpty())
1599 {
1600 ref+=clname;
1601 }
1602 if (!anchor.isEmpty())
1603 {
1604 ref+='_';
1605 ref+=anchor;
1606 }
1607 writeRTFReference(ref);
1608 endEmphasis();
1609 m_t << ")";
1610}
1611
1613{
1614 DBG_RTF(m_t << "{\\comment startTitleHead}\n")
1615 int level = 2 + m_hierarchyLevel;
1616 QCString heading;
1617 heading.sprintf("Heading%d", level);
1618 // beginRTFSection();
1619 m_t << rtf_Style_Reset << rtf_Style[heading.str()].reference() << "\n";
1620}
1621
1623{
1624 DBG_RTF(m_t << "{\\comment endTitleHead}\n")
1625 m_t << "\\par " << rtf_Style_Reset << "\n";
1626 if (!name.isEmpty())
1627 {
1628 // make table of contents entry
1629 int level = 2 + m_hierarchyLevel;
1630 m_t << "{\\tc\\tcl" << level << " \\v ";
1631 docify(name);
1632 m_t << "}\n";
1633
1634 // make an index entry
1635 addIndexItem(name,QCString());
1636 }
1637 if (!fileName.isEmpty())
1638 {
1640 }
1641}
1642
1643void RTFGenerator::startGroupHeader(const QCString &,int extraIndent)
1644{
1645 DBG_RTF(m_t << "{\\comment startGroupHeader}\n")
1647 extraIndent += m_hierarchyLevel;
1648 if (extraIndent>=2)
1649 {
1650 m_t << rtf_Style["Heading5"].reference();
1651 }
1652 else if (extraIndent==1)
1653 {
1654 m_t << rtf_Style["Heading4"].reference();
1655 }
1656 else // extraIndent==0
1657 {
1658 m_t << rtf_Style["Heading3"].reference();
1659 }
1660 m_t << "\n";
1661}
1662
1664{
1665 DBG_RTF(m_t << "{\\comment endGroupHeader}\n")
1666 m_t << "\\par\n";
1667 m_t << rtf_Style_Reset << "\n";
1668}
1669
1671 const QCString &memname,
1672 const QCString &,
1673 const QCString &,
1674 int,
1675 int,
1676 bool showInline)
1677{
1678 DBG_RTF(m_t << "{\\comment startMemberDoc}\n")
1679 if (!memname.isEmpty() && memname[0]!='@')
1680 {
1681 addIndexItem(memname,clname);
1682 addIndexItem(clname,memname);
1683 }
1684
1685 int level = 4 + m_hierarchyLevel;
1686 if (showInline)
1687 ++level;
1688 if (level > 5)
1689 level = 5;
1690 if (level < 1)
1691 level = 1;
1692 m_t << rtf_Style_Reset << rtf_Style[QCString().sprintf("Heading%d", level).str()].reference();
1693 //styleStack.push(rtf_Style_Heading4);
1694 m_t << "{\n";
1695 //printf("RTFGenerator::startMemberDoc() '%s'\n",rtf_Style["Heading4"].reference());
1696 startBold();
1697 m_t << "\n";
1698}
1699
1701{
1702 DBG_RTF(m_t << "{\\comment endMemberDoc}\n")
1703 //const QCString &style = styleStack.pop();
1704 //printf("RTFGenerator::endMemberDoc() '%s'\n",style);
1705 //ASSERT(style==rtf_Style["Heading4"].reference());
1706 endBold();
1707 m_t << "}\n";
1708 newParagraph();
1709}
1710
1712 const QCString &,const QCString &,
1713 const QCString &
1714 )
1715{
1716 DBG_RTF(m_t << "{\\comment startDoxyAnchor}\n")
1717}
1718
1719void RTFGenerator::endDoxyAnchor(const QCString &fName,const QCString &anchor)
1720{
1721 QCString ref;
1722 if (!fName.isEmpty())
1723 {
1724 ref+=stripPath(fName);
1725 }
1726 if (!anchor.isEmpty())
1727 {
1728 ref+='_';
1729 ref+=anchor;
1730 }
1731
1732 DBG_RTF(m_t << "{\\comment endDoxyAnchor}\n")
1733 m_t << "{\\bkmkstart ";
1734 m_t << rtfFormatBmkStr(ref);
1735 m_t << "}\n";
1736 m_t << "{\\bkmkend ";
1737 m_t << rtfFormatBmkStr(ref);
1738 m_t << "}\n";
1739}
1740
1742{
1743 DBG_RTF(m_t << "{\\comment addLabel}\n")
1744}
1745
1746
1748{
1749 if (!s1.isEmpty())
1750 {
1751 m_t << "{\\xe \\v ";
1752 docify(s1);
1753 if (!s2.isEmpty())
1754 {
1755 m_t << "\\:";
1756 docify(s2);
1757 }
1758 m_t << "}\n";
1759 }
1760}
1761
1763{
1765 DBG_RTF(m_t << "{\\comment (startIndent) }\n")
1766 m_t << "{\n";
1768}
1769
1771{
1772 m_t << "}\n";
1774}
1775
1776
1778{
1779 DBG_RTF(m_t << "{\\comment (startMemberDescription)}\n")
1780 m_t << "{\n";
1783 startEmphasis();
1784}
1785
1787{
1788 DBG_RTF(m_t << "{\\comment (endMemberDescription)}\n")
1789 endEmphasis();
1791 m_t << "\\par";
1792 m_t << "}\n";
1794}
1795
1797{
1798 DBG_RTF(m_t << "{\\comment (startDescForItem) }\n")
1799}
1800
1802{
1803 DBG_RTF(m_t << "{\\comment (endDescForItem) }\n")
1804}
1805
1807{
1808 DBG_RTF(m_t << "{\\comment (startSection)}\n")
1809 m_t << "{";
1811 int num=SectionType::MaxLevel;
1812 switch(type.level())
1813 {
1814 case SectionType::Page: num=2+m_hierarchyLevel; break;
1815 case SectionType::Section: num=3+m_hierarchyLevel; break;
1816 case SectionType::Subsection: // fall through
1817 case SectionType::Subsubsection: // fall through
1818 case SectionType::Paragraph: // fall through
1819 case SectionType::Subparagraph: // fall through
1821 default: ASSERT(0); break;
1822 }
1823 num = std::clamp(num, SectionType::MinLevel, SectionType::MaxLevel);
1824 QCString heading;
1825 heading.sprintf("Heading%d",num);
1826 // set style
1827 m_t << rtf_Style[heading.str()].reference();
1828 // make table of contents entry
1829 m_t << "{\\tc\\tcl" << num << " \\v ";
1830 docify(title);
1831 m_t << "}\n";
1832}
1833
1835{
1836 DBG_RTF(m_t << "{\\comment (endSection)}\n")
1837 // make bookmark
1839 newParagraph();
1840 writeAnchor(QCString(),lab);
1841 m_t << "}";
1842}
1843
1845{
1846 if (str.isEmpty()) return;
1847 m_t << docifyToString(str);
1849}
1850
1852{
1853 char cs[2];
1854 cs[0]=c;
1855 cs[1]=0;
1856 docify(cs);
1857}
1858
1860{
1861 DBG_RTF(m_t << "{\\comment startClassDiagram }\n")
1862}
1863
1865 const QCString &fileName,const QCString &)
1866{
1867 newParagraph();
1868
1869 // create a png file
1871
1872 // display the file
1873 m_t << "{\n";
1874 m_t << rtf_Style_Reset << "\n";
1875 m_t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
1876 m_t << fileName << ".png\"";
1877 m_t << " \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par\n";
1878 m_t << "}\n";
1879}
1880
1882{
1883 DBG_RTF(m_t << "{\\comment startMemberItem }\n")
1884 m_t << rtf_Style_Reset << rtf_BList_DepthStyle() << "\n"; // set style to appropriate depth
1885}
1886
1888{
1889 DBG_RTF(m_t << "{\\comment endMemberItem }\n")
1890 newParagraph();
1891}
1892
1894{
1895 QCString anchor;
1896 if (!fileName.isEmpty())
1897 {
1898 anchor+=stripPath(fileName);
1899 }
1900 if (!fileName.isEmpty() && !name.isEmpty())
1901 {
1902 anchor+='_';
1903 }
1904 if (!name.isEmpty())
1905 {
1906 anchor+=name;
1907 }
1908 //printf("writeAnchor(%s->%s)\n",qPrint(anchor),qPrint(rtfFormatBmkStr(anchor)));
1909
1910 DBG_RTF(m_t << "{\\comment writeAnchor (" << anchor << ")}\n")
1911 m_t << "{\\bkmkstart " << rtfFormatBmkStr(anchor) << "}\n";
1912 m_t << "{\\bkmkend " << rtfFormatBmkStr(anchor) << "}\n";
1913}
1914
1916{
1917 m_t << "{\\field\\fldedit {\\*\\fldinst PAGEREF ";
1918 m_t << rtfFormatBmkStr(stripPath(label));
1919 m_t << " \\\\*MERGEFORMAT}{\\fldrslt pagenum}}";
1920}
1921
1923{
1924 m_t << "\\~ ";
1925}
1926
1927
1929{
1930 m_t << "\n";
1931 DBG_RTF(m_t << "{\\comment (startMemberList) }\n")
1932 m_t << "{\n";
1933#ifdef DELETEDCODE
1934 if (!insideTabbing)
1935 m_t << "\\begin{CompactItemize}\n";
1936#endif
1937}
1938
1940{
1941 DBG_RTF(m_t << "{\\comment (endMemberList) }\n")
1942 m_t << "}\n";
1943#ifdef DELETEDCODE
1944 if (!insideTabbing)
1945 m_t << "\\end{CompactItemize}\n";
1946#endif
1947}
1948
1949void RTFGenerator::startDescTable(const QCString &title,const bool hasInits)
1950{
1951 DBG_RTF(m_t << "{\\comment (startDescTable) }\n")
1952 m_t << "{\\par\n";
1953 m_t << "{" << rtf_Style["Heading5"].reference() << "\n";
1954 docify(title);
1955 m_t << ":\\par}\n";
1957 m_t << "\\trowd \\trgaph108\\trleft426\\tblind426"
1958 "\\trbrdrt\\brdrs\\brdrw10\\brdrcf15 "
1959 "\\trbrdrl\\brdrs\\brdrw10\\brdrcf15 "
1960 "\\trbrdrb\\brdrs\\brdrw10\\brdrcf15 "
1961 "\\trbrdrr\\brdrs\\brdrw10\\brdrcf15 "
1962 "\\trbrdrh\\brdrs\\brdrw10\\brdrcf15 "
1963 "\\trbrdrv\\brdrs\\brdrw10\\brdrcf15 \n";
1964 int columnPos2[2] = { 25, 100 };
1965 int columnPos3[3] = { 25, 45, 100 };
1966 for (int i=0;i<(hasInits?3:2);i++)
1967 {
1968 m_t << "\\clvertalt\\clbrdrt\\brdrs\\brdrw10\\brdrcf15 "
1969 "\\clbrdrl\\brdrs\\brdrw10\\brdrcf15 "
1970 "\\clbrdrb\\brdrs\\brdrw10\\brdrcf15 "
1971 "\\clbrdrr \\brdrs\\brdrw10\\brdrcf15 "
1972 "\\cltxlrtb "
1973 "\\cellx" << (rtf_pageWidth*(hasInits?columnPos3[i]:columnPos2[i])/100) << "\n";
1974 }
1975 m_t << "\\pard \\widctlpar\\intbl\\adjustright\n";
1976}
1977
1979{
1980 DBG_RTF(m_t << "{\\comment (endDescTable)}\n")
1981 m_t << "}\n";
1982}
1983
1987
1991
1993{
1994 DBG_RTF(m_t << "{\\comment (startDescTableTitle) }\n")
1995 m_t << "{";
1996 m_t << rtf_Style["BodyText"].reference();
1997}
1998
2000{
2001 DBG_RTF(m_t << "{\\comment (endDescTableTitle) }\n")
2002 m_t << "\\cell }";
2003}
2004
2006{
2007 DBG_RTF(m_t << "{\\comment (startDescTableInit) }" << endl)
2008 m_t << "{";
2009 m_t << rtf_Style["BodyText"].reference();
2010 m_t << "\\qr ";
2011}
2012
2014{
2015 DBG_RTF(m_t << "{\\comment (endDescTableInit) }" << endl)
2016 m_t << "\\cell }";
2017}
2018
2020{
2021 DBG_RTF(m_t << "{\\comment (startDescTableData) }\n")
2022 m_t << "{";
2023}
2024
2026{
2027 DBG_RTF(m_t << "{\\comment (endDescTableData) }\n")
2028 m_t << "\\cell }{\\row }\n";
2029}
2030
2031// a style for list formatted as a "bulleted list"
2032
2034{
2035 return std::min(m_indentLevel,maxIndentLevels-1);
2036}
2037
2039{
2040 m_indentLevel++;
2042 {
2044 int m = maxIndentLevels;
2045 err("Maximum indent level ({}) exceeded while generating RTF output!\n",m);
2046 }
2047 m_codeGen->setIndentLevel(m_indentLevel);
2048}
2049
2051{
2052 m_indentLevel--;
2053 if (m_indentLevel<0)
2054 {
2055 err("Negative indent level while generating RTF output!\n");
2056 m_indentLevel=0;
2057 }
2058 m_codeGen->setIndentLevel(m_indentLevel);
2059}
2060
2061// a style for list formatted with "list continue" style
2063{
2064 QCString n=makeIndexName("ListContinue",indentLevel());
2065 return rtf_Style[n.str()].reference();
2066}
2067
2068// a style for list formatted as a "latext style" table of contents
2070{
2071 QCString n=makeIndexName("LatexTOC",indentLevel());
2072 return rtf_Style[n.str()].reference();
2073}
2074
2075// a style for list formatted as a "bullet" style
2077{
2078 QCString n=makeIndexName("ListBullet",indentLevel());
2079 return rtf_Style[n.str()].reference();
2080}
2081
2082// a style for list formatted as a "enumeration" style
2084{
2085 QCString n=makeIndexName("ListEnum",indentLevel());
2086 return rtf_Style[n.str()].reference();
2087}
2088
2090{
2091 QCString n=makeIndexName("DescContinue",indentLevel());
2092 return rtf_Style[n.str()].reference();
2093}
2094
2096{
2097 DBG_RTF(m_t << "{\\comment startTextBlock}\n")
2098 m_t << "{\n";
2100 if (dense) // no spacing between "paragraphs"
2101 {
2102 m_t << rtf_Style["DenseText"].reference();
2103 }
2104 else // some spacing
2105 {
2106 m_t << rtf_Style["BodyText"].reference();
2107 }
2108}
2109
2110void RTFGenerator::endTextBlock(bool /*paraBreak*/)
2111{
2112 newParagraph();
2113 DBG_RTF(m_t << "{\\comment endTextBlock}\n")
2114 m_t << "}\n";
2115 //m_omitParagraph = TRUE;
2116}
2117
2119{
2120 if (!m_omitParagraph)
2121 {
2122 DBG_RTF(m_t << "{\\comment (newParagraph)}\n")
2123 m_t << "\\par\n";
2124 }
2126}
2127
2129{
2130 DBG_RTF(m_t << "{\\comment startParagraph}\n")
2131 newParagraph();
2132 m_t << "{\n";
2133 if (QCString(txt) == "reference") m_t << "\\ql\n";
2134}
2135
2137{
2138 DBG_RTF(m_t << "{\\comment endParagraph}\n")
2139 m_t << "}\\par\n";
2141}
2142
2144{
2145 DBG_RTF(m_t << "{\\comment startMemberSubtitle}\n")
2146 m_t << "{\n";
2148}
2149
2151{
2152 DBG_RTF(m_t << "{\\comment endMemberSubtitle}\n")
2153 newParagraph();
2154 m_t << "}\n";
2155}
2156
2157bool isLeadBytes(int c)
2158{
2159 bool result=false; // for SBCS Codepages (cp1252,1251 etc...);
2160
2161 QCString codePage = theTranslator->trRTFansicp();
2162
2163 if (codePage == "932") // cp932 (Japanese Shift-JIS)
2164 {
2165 result = (0x81<=c && c<=0x9f) || (0xe0<=c && c<=0xfc);
2166 }
2167 else if (codePage == "936") // cp936 (Simplified Chinese GBK)
2168 {
2169 result = 0x81<=c && c<=0xFE;
2170 }
2171 else if (codePage == "949") // cp949 (Korean)
2172 {
2173 result = 0x81<=c && c<=0xFE;
2174 }
2175 else if (codePage == "950") // cp950 (Traditional Chinese Big5)
2176 {
2177 result = 0x81<=c && c<=0xFE;
2178 }
2179
2180 return result;
2181}
2182
2183
2184// note: function is not reentrant!
2185static void encodeForOutput(TextStream &t,const QCString &s)
2186{
2187 if (s==nullptr) return;
2188 QCString encoding;
2189 bool converted=FALSE;
2190 size_t l = s.length();
2191 static std::vector<char> enc;
2192 if (l*4>enc.size()) enc.resize(l*4); // worst case
2193 encoding.sprintf("CP%s",qPrint(theTranslator->trRTFansicp()));
2194 if (!encoding.isEmpty())
2195 {
2196 // convert from UTF-8 back to the output encoding
2197 void *cd = portable_iconv_open(encoding.data(),"UTF-8");
2198 if (cd!=reinterpret_cast<void *>(-1))
2199 {
2200 size_t iLeft=l;
2201 size_t oLeft=enc.size();
2202 const char *inputPtr = s.data();
2203 char *outputPtr = &enc[0];
2204 if (!portable_iconv(cd, &inputPtr, &iLeft, &outputPtr, &oLeft))
2205 {
2206 enc.resize(enc.size()-oLeft);
2207 converted=TRUE;
2208 }
2210 }
2211 }
2212 if (!converted) // if we did not convert anything, copy as is.
2213 {
2214 memcpy(enc.data(),s.data(),l);
2215 enc.resize(l);
2216 }
2217 bool multiByte = FALSE;
2218
2219 for (size_t i=0;i<enc.size();i++)
2220 {
2221 uint8_t c = static_cast<uint8_t>(enc.at(i));
2222
2223 if (c>=0x80 || multiByte)
2224 {
2225 char esc[10];
2226 qsnprintf(esc,10,"\\'%X",c); // escape sequence for SBCS and DBCS(1st&2nd bytes).
2227 t << esc;
2228
2229 if (!multiByte)
2230 {
2231 multiByte = isLeadBytes(c); // It may be DBCS Codepages.
2232 }
2233 else
2234 {
2235 multiByte = FALSE; // end of Double Bytes Character.
2236 }
2237 }
2238 else
2239 {
2240 t << c;
2241 }
2242 }
2243}
2244
2245/**
2246 * VERY brittle routine inline RTF's included by other RTF's.
2247 * it is recursive and ugly.
2248 */
2249static bool preProcessFile(Dir &d,const QCString &infName, TextStream &t, bool bIncludeHeader=true, bool removeFile = true)
2250{
2251 static bool rtfDebug = Debug::isFlagSet(Debug::Rtf);
2252 std::ifstream f = Portable::openInputStream(infName);
2253 if (!f.is_open())
2254 {
2255 err("problems opening rtf file '{}' for reading\n",infName);
2256 return false;
2257 }
2258
2259 const int maxLineLength = 10240;
2260 static QCString lineBuf(maxLineLength, QCString::ExplicitSize);
2261
2262 // scan until find end of header
2263 // this is EXTREEEEEEEMLY brittle. It works on OUR rtf
2264 // files because the first line before the body
2265 // ALWAYS contains "{\comment begin body}"
2266 std::string line;
2267 while (getline(f,line))
2268 {
2269 line+='\n';
2270 if (line.find("\\comment begin body")!=std::string::npos) break;
2271 if (bIncludeHeader) encodeForOutput(t,line.c_str());
2272 }
2273
2274 std::string prevLine;
2275 bool first=true;
2276 while (getline(f,line))
2277 {
2278 line+='\n';
2279 size_t pos=prevLine.find("INCLUDETEXT \"");
2280 if (pos!=std::string::npos)
2281 {
2282 size_t startNamePos = prevLine.find('"',pos)+1;
2283 size_t endNamePos = prevLine.find('"',startNamePos);
2284 std::string fileName = prevLine.substr(startNamePos,endNamePos-startNamePos);
2285 DBG_RTF(t << "{\\comment begin include " << fileName << "}\n")
2286 if (!preProcessFile(d,fileName.c_str(),t,FALSE)) return FALSE;
2287 DBG_RTF(t << "{\\comment end include " << fileName << "}\n")
2288 }
2289 else if (!first) // no INCLUDETEXT on this line
2290 {
2291 encodeForOutput(t,prevLine.c_str());
2292 }
2293 prevLine = line;
2294 first=false;
2295 }
2296 if (!bIncludeHeader) // skip final '}' in case we don't include headers
2297 {
2298 size_t pos = line.rfind('}');
2299 if (pos==std::string::npos)
2300 {
2301 err("Strange, the last char was not a '}}'\n");
2302 pos = line.length();
2303 }
2304 encodeForOutput(t,line.substr(0,pos).c_str());
2305 }
2306 else
2307 {
2308 encodeForOutput(t,line.c_str());
2309 }
2310 f.close();
2311 // remove temporary file
2312 if (!rtfDebug && removeFile) removeSet.insert(FileInfo(d.filePath(infName.str())).absFilePath());
2313 return TRUE;
2314}
2315
2317{
2318 DBG_RTF(m_t << "{\\comment (startDotGraph)}\n")
2319}
2320
2322{
2323 newParagraph();
2324
2326
2327 // display the file
2328 m_t << "{\n";
2329 m_t << rtf_Style_Reset << "\n";
2330 m_t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
2331 QCString imgExt = getDotImageExtension();
2332 m_t << fn << "." << imgExt;
2333 m_t << "\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par\n";
2334 m_t << "}\n";
2335 newParagraph();
2336 DBG_RTF(m_t << "{\\comment (endDotGraph)}\n")
2337}
2338
2340{
2341 DBG_RTF(m_t << "{\\comment (startInclDepGraph)}\n")
2342}
2343
2345{
2346 newParagraph();
2347
2349
2350 // display the file
2351 m_t << "{\n";
2352 m_t << rtf_Style_Reset << "\n";
2353 m_t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
2354 QCString imgExt = getDotImageExtension();
2355 m_t << fn << "." << imgExt;
2356 m_t << "\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par\n";
2357 m_t << "}\n";
2358 DBG_RTF(m_t << "{\\comment (endInclDepGraph)}\n")
2359}
2360
2364
2368
2370{
2371 DBG_RTF(m_t << "{\\comment (startCallGraph)}\n")
2372}
2373
2375{
2376 newParagraph();
2377
2379
2380 // display the file
2381 m_t << "{\n";
2382 m_t << rtf_Style_Reset << "\n";
2383 m_t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
2384 QCString imgExt = getDotImageExtension();
2385 m_t << fn << "." << imgExt;
2386 m_t << "\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par\n";
2387 m_t << "}\n";
2388 DBG_RTF(m_t << "{\\comment (endCallGraph)}\n")
2389}
2390
2392{
2393 DBG_RTF(m_t << "{\\comment (startDirDepGraph)}\n")
2394}
2395
2397{
2398 newParagraph();
2399
2401
2402 // display the file
2403 m_t << "{\n";
2404 m_t << rtf_Style_Reset << "\n";
2405 m_t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
2406 QCString imgExt = getDotImageExtension();
2407 m_t << fn << "." << imgExt;
2408 m_t << "\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par\n";
2409 m_t << "}\n";
2410 DBG_RTF(m_t << "{\\comment (endDirDepGraph)}\n")
2411}
2412
2413/** Tests the integrity of the result by counting brackets.
2414 *
2415 */
2417{
2418 int bcount=0;
2419 int line=1;
2420 int c=0;
2421 std::ifstream f = Portable::openInputStream(name);
2422 if (f.is_open())
2423 {
2424 while ((c=f.get())!=-1)
2425 {
2426 if (c=='\\') // escape char
2427 {
2428 c=f.get();
2429 if (c==-1) break;
2430 }
2431 else if (c=='{') // open bracket
2432 {
2433 bcount++;
2434 }
2435 else if (c=='}') // close bracket
2436 {
2437 bcount--;
2438 if (bcount<0)
2439 {
2440 goto err;
2441 break;
2442 }
2443 }
2444 else if (c=='\n') // newline
2445 {
2446 line++;
2447 }
2448 }
2449 }
2450 if (bcount==0) return; // file is OK.
2451err:
2452 err("RTF integrity test failed at line {:d} of {} due to a bracket mismatch.\n"
2453 " Please try to create a small code example that produces this error \n"
2454 " and send that to doxygen@gmail.com.\n",line,name);
2455}
2456
2457/**
2458 * This is an API to a VERY brittle RTF preprocessor that combines nested
2459 * RTF files. This version replaces the infile with the new file
2460 */
2462{
2463 static bool rtfDebug = Debug::isFlagSet(Debug::Rtf);
2464
2465 Dir d(path.str());
2466 // store the original directory
2467 if (!d.exists())
2468 {
2469 err("Output dir {} does not exist!\n",path);
2470 return FALSE;
2471 }
2472 std::string oldDir = Dir::currentDirPath();
2473
2474 // go to the html output directory (i.e. path)
2476 Dir thisDir;
2477
2478 QCString combinedName = path+"/combined.rtf";
2479 QCString mainRTFName = path+"/"+name;
2480
2481 std::ofstream f = Portable::openOutputStream(combinedName);
2482 if (!f.is_open())
2483 {
2484 err("Failed to open {} for writing!\n",combinedName);
2485 Dir::setCurrent(oldDir);
2486 return FALSE;
2487 }
2488 TextStream outt(&f);
2489
2490 if (!preProcessFile(thisDir,mainRTFName,outt,true,false))
2491 {
2492 // it failed, remove the temp file
2493 outt.flush();
2494 f.close();
2495 if (!rtfDebug) removeSet.insert(FileInfo(thisDir.filePath(combinedName.str())).absFilePath());
2496 Dir::setCurrent(oldDir);
2497 return FALSE;
2498 }
2499
2500 // everything worked, move the files
2501 outt.flush();
2502 f.close();
2503 if (!rtfDebug)
2504 {
2505 thisDir.remove(mainRTFName.str());
2506 }
2507 else
2508 {
2509 thisDir.rename(mainRTFName.str(),mainRTFName.str() + ".org");
2510 }
2511 thisDir.rename(combinedName.str(),mainRTFName.str());
2512
2513 testRTFOutput(mainRTFName);
2514
2515 QCString rtfOutputDir = Dir::currentDirPath();
2516 for (auto &s : removeSet)
2517 {
2518 QCString s1(s.c_str());
2519 if (s1.startsWith(rtfOutputDir)) Portable::unlink(s1);
2520 }
2521
2522 Dir::setCurrent(oldDir);
2523 return TRUE;
2524}
2525
2527{
2528 DBG_RTF(m_t << "{\\comment startMemberGroupHeader}\n")
2529 m_t << "{\n";
2530 if (hasHeader) incIndentLevel();
2531 m_t << rtf_Style_Reset << rtf_Style["GroupHeader"].reference();
2532}
2533
2535{
2536 DBG_RTF(m_t << "{\\comment endMemberGroupHeader}\n")
2537 newParagraph();
2539}
2540
2542{
2543 DBG_RTF(m_t << "{\\comment startMemberGroupDocs}\n")
2544 startEmphasis();
2545}
2546
2548{
2549 DBG_RTF(m_t << "{\\comment endMemberGroupDocs}\n")
2550 endEmphasis();
2551 newParagraph();
2552}
2553
2555{
2556 DBG_RTF(m_t << "{\\comment startMemberGroup}\n")
2558}
2559
2561{
2562 DBG_RTF(m_t << "{\\comment endMemberGroup}\n")
2563 if (hasHeader) decIndentLevel();
2564 m_t << "}";
2565}
2566
2568{
2569 DBG_RTF(m_t << "{\\comment (startExamples)}\n")
2570 m_t << "{"; // ends at endDescList
2571 m_t << "{"; // ends at endDescTitle
2572 startBold();
2573 newParagraph();
2574 docify(theTranslator->trExamples());
2575 endBold();
2576 m_t << "}";
2577 newParagraph();
2580}
2581
2583{
2584 DBG_RTF(m_t << "{\\comment (endExamples)}\n")
2586 newParagraph();
2589 m_t << "}";
2590}
2591
2593{
2594 DBG_RTF(m_t << "{\\comment (startParameterType)}\n")
2595 if (!first && !key.isEmpty())
2596 {
2597 m_t << " " << key << " ";
2598 }
2599}
2600
2602{
2603 DBG_RTF(m_t << "{\\comment (endParameterType)}\n")
2604 m_t << " ";
2605}
2606
2607void RTFGenerator::exceptionEntry(const QCString &prefix,bool closeBracket)
2608{
2609 DBG_RTF(m_t << "{\\comment (exceptionEntry)}\n")
2610 if (!prefix.isEmpty())
2611 {
2612 m_t << " " << prefix << "(";
2613 }
2614 else if (closeBracket)
2615 {
2616 m_t << ")";
2617 }
2618 m_t << " ";
2619}
2620
2621void RTFGenerator::writeDoc(const IDocNodeAST *ast,const Definition *ctx,const MemberDef *,int)
2622{
2623 auto astImpl = dynamic_cast<const DocNodeAST*>(ast);
2624 if (astImpl)
2625 {
2627 std::visit(visitor,astImpl->root);
2628 }
2630}
2631
2633{
2634 DBG_RTF(m_t << "{\\comment (rtfwriteRuler_doubleline)}\n")
2635 m_t << "{\\pard\\widctlpar\\brdrb\\brdrdb\\brdrw15\\brsp20 \\adjustright \\par}\n";
2636}
2637
2639{
2640 DBG_RTF(m_t << "{\\comment (rtfwriteRuler_emboss)}\n")
2641 m_t << "{\\pard\\widctlpar\\brdrb\\brdremboss\\brdrw15\\brsp20 \\adjustright \\par}\n";
2642}
2643
2645{
2646 DBG_RTF(m_t << "{\\comment (rtfwriteRuler_thick)}\n")
2647 m_t << "{\\pard\\widctlpar\\brdrb\\brdrs\\brdrw75\\brsp20 \\adjustright \\par}\n";
2648}
2649
2651{
2652 DBG_RTF(m_t << "{\\comment (rtfwriteRuler_thin)}\n")
2653 m_t << "{\\pard\\widctlpar\\brdrb\\brdrs\\brdrw5\\brsp20 \\adjustright \\par}\n";
2654}
2655
2657{
2658 DBG_RTF(m_t << "{\\comment (startConstraintList)}\n")
2659 m_t << "{"; // ends at endConstraintList
2660 m_t << "{";
2661 startBold();
2662 newParagraph();
2663 docify(header);
2664 endBold();
2665 m_t << "}";
2666 newParagraph();
2669}
2670
2672{
2673 DBG_RTF(m_t << "{\\comment (startConstraintParam)}\n")
2674 startEmphasis();
2675}
2676
2678{
2679 DBG_RTF(m_t << "{\\comment (endConstraintParam)}\n")
2680 endEmphasis();
2681 m_t << " : ";
2682}
2683
2685{
2686 DBG_RTF(m_t << "{\\comment (startConstraintType)}\n")
2687 startEmphasis();
2688}
2689
2691{
2692 DBG_RTF(m_t << "{\\comment (endConstraintType)}\n")
2693 endEmphasis();
2694 m_t << " ";
2695}
2696
2698{
2699 DBG_RTF(m_t << "{\\comment (startConstraintDocs)}\n")
2700}
2701
2703{
2704 DBG_RTF(m_t << "{\\comment (endConstraintDocs)}\n")
2705 newParagraph();
2706}
2707
2709{
2710 DBG_RTF(m_t << "{\\comment (endConstraintList)}\n")
2711 newParagraph();
2714 m_t << "}";
2715}
2716
2718{
2719 DBG_RTF(m_t << "{\\comment (startIndexListItem)}\n")
2720}
2721
2723{
2724 DBG_RTF(m_t << "{\\comment (endIndexListItem)}\n")
2725 m_t << "\\par\n";
2726}
2727
2729{
2730 DBG_RTF(m_t << "{\\comment (startInlineHeader)}\n")
2731 m_t << "{\n";
2732 m_t << rtf_Style_Reset << rtf_Style["Heading5"].reference();
2733 startBold();
2734}
2735
2737{
2738 DBG_RTF(m_t << "{\\comment (endInlineHeader)}\n")
2739 endBold();
2740 m_t << "\\par";
2741 m_t << "}\n";
2742}
2743
2745{
2746 DBG_RTF(m_t << "{\\comment (startMemberDocSimple)}\n")
2747 m_t << "{\\par\n";
2748 m_t << "{" << rtf_Style["Heading5"].reference() << "\n";
2749 if (isEnum)
2750 {
2751 m_t << theTranslator->trEnumerationValues();
2752 }
2753 else
2754 {
2755 m_t << theTranslator->trCompoundMembers();
2756 }
2757 m_t << ":\\par}\n";
2759 m_t << "\\trowd \\trgaph108\\trleft426\\tblind426"
2760 "\\trbrdrt\\brdrs\\brdrw10\\brdrcf15 "
2761 "\\trbrdrl\\brdrs\\brdrw10\\brdrcf15 "
2762 "\\trbrdrb\\brdrs\\brdrw10\\brdrcf15 "
2763 "\\trbrdrr\\brdrs\\brdrw10\\brdrcf15 "
2764 "\\trbrdrh\\brdrs\\brdrw10\\brdrcf15 "
2765 "\\trbrdrv\\brdrs\\brdrw10\\brdrcf15 \n";
2766 int n=3,columnPos[3] = { 25, 50, 100 };
2767 if (isEnum)
2768 {
2769 columnPos[0]=30;
2770 columnPos[1]=100;
2771 n=2;
2772 }
2773 for (int i=0;i<n;i++)
2774 {
2775 m_t << "\\clvertalt\\clbrdrt\\brdrs\\brdrw10\\brdrcf15 "
2776 "\\clbrdrl\\brdrs\\brdrw10\\brdrcf15 "
2777 "\\clbrdrb\\brdrs\\brdrw10\\brdrcf15 "
2778 "\\clbrdrr \\brdrs\\brdrw10\\brdrcf15 "
2779 "\\cltxlrtb "
2780 "\\cellx" << (rtf_pageWidth*columnPos[i]/100) << "\n";
2781 }
2782 m_t << "\\pard \\widctlpar\\intbl\\adjustright\n";
2783}
2784
2786{
2787 DBG_RTF(m_t << "{\\comment (endMemberDocSimple)}\n")
2788 m_t << "}\n";
2789}
2790
2792{
2793 DBG_RTF(m_t << "{\\comment (startInlineMemberType)}\n")
2794 m_t << "{\\qr ";
2795}
2796
2798{
2799 DBG_RTF(m_t << "{\\comment (endInlineMemberType)}\n")
2800 m_t << "\\cell }";
2801}
2802
2804{
2805 DBG_RTF(m_t << "{\\comment (startInlineMemberName)}\n")
2806 m_t << "{";
2807}
2808
2810{
2811 DBG_RTF(m_t << "{\\comment (endInlineMemberName)}\n")
2812 m_t << "\\cell }";
2813}
2814
2816{
2817 DBG_RTF(m_t << "{\\comment (startInlineMemberDoc)}\n")
2818 m_t << "{";
2819}
2820
2822{
2823 DBG_RTF(m_t << "{\\comment (endInlineMemberDoc)}\n")
2824 m_t << "\\cell }{\\row }\n";
2825}
2826
2828{
2829}
2830
2831void RTFGenerator::writeLabel(const QCString &l,bool isLast)
2832{
2833 m_t << "{\\f2 [" << l << "]}";
2834 if (!isLast) m_t << ", ";
2835}
2836
2838{
2839}
2840
2842 const QCString &/*id*/,const QCString &ref,
2843 const QCString &file, const QCString &anchor,
2844 const QCString &title, const QCString &name)
2845{
2847 m_t << rtf_Style["Heading4"].reference();
2848 m_t << "\n";
2849 m_t << theTranslator->trInheritedFrom(docifyToString(title), objectLinkToString(ref, file, anchor, name));
2850 m_t << "\\par\n";
2851 m_t << rtf_Style_Reset << "\n";
2852}
2853
2855{
2856 if (openBracket) m_t << "(";
2857}
2858
2859void RTFGenerator::endParameterExtra(bool last,bool /* emptyList */, bool closeBracket)
2860{
2861 if (last && closeBracket)
2862 {
2863 m_t << ")";
2864 }
2865}
2866
2867//----------------------------------------------------------------------
2868
2869static std::mutex g_rtfFormatMutex;
2870static std::unordered_map<std::string,std::string> g_tagMap;
2871static QCString g_nextTag( "AAAAAAAAAA" );
2872
2874{
2875 std::lock_guard<std::mutex> lock(g_rtfFormatMutex);
2876
2877 // To overcome the 40-character tag limitation, we
2878 // substitute a short arbitrary string for the name
2879 // supplied, and keep track of the correspondence
2880 // between names and strings.
2881 auto it = g_tagMap.find(name.str());
2882 if (it!=g_tagMap.end()) // already known
2883 {
2884 return QCString(it->second);
2885 }
2886
2887 QCString tag = g_nextTag;
2888 auto result = g_tagMap.emplace(name.str(), g_nextTag.str());
2889
2890 if (result.second) // new item was added
2891 {
2892 // increment the next tag.
2893
2894 char* nxtTag = g_nextTag.rawData() + g_nextTag.length() - 1;
2895 for ( unsigned int i = 0; i < g_nextTag.length(); ++i, --nxtTag )
2896 {
2897 if ( ( ++(*nxtTag) ) > 'Z' )
2898 {
2899 *nxtTag = 'A';
2900 }
2901 else
2902 {
2903 // Since there was no carry, we can stop now
2904 break;
2905 }
2906 }
2907 }
2908
2909 Debug::print(Debug::Rtf,0,"Name = {} RTF_tag = {}\n",name,tag);
2910 return tag;
2911}
2912
constexpr auto prefix
Definition anchor.cpp:44
Class representing a built-in class diagram.
Definition diagram.h:31
void writeImage(TextStream &t, const QCString &path, const QCString &relPath, const QCString &file, bool generateMap=true) const
Definition diagram.cpp:1369
@ Rtf
Definition debug.h:43
static bool isFlagSet(const DebugMask mask)
Definition debug.cpp:132
static void print(DebugMask mask, int prio, fmt::format_string< Args... > fmt, Args &&... args)
Definition debug.h:76
The common base class of all entity definitions found in the sources.
Definition definition.h:76
virtual QCString getDefFileExtension() const =0
Class representing a directory in the file system.
Definition dir.h:75
static std::string currentDirPath()
Definition dir.cpp:342
std::string absPath() const
Definition dir.cpp:364
bool mkdir(const std::string &path, bool acceptsAbsPath=true) const
Definition dir.cpp:295
bool remove(const std::string &path, bool acceptsAbsPath=true) const
Definition dir.cpp:314
std::string filePath(const std::string &path, bool acceptsAbsPath=true) const
Definition dir.cpp:280
bool rename(const std::string &orgName, const std::string &newName, bool acceptsAbsPath=true) const
Definition dir.cpp:321
static bool setCurrent(const std::string &path)
Definition dir.cpp:350
bool exists() const
Definition dir.cpp:257
Class representing the abstract syntax tree of a documentation block.
Definition docnode.h:1466
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.
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
opaque representation of the abstract syntax tree (AST)
Definition docparser.h:50
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 startsWith(const char *s) const
Definition qcstring.h:492
bool isEmpty() const
Returns TRUE iff the string is empty.
Definition qcstring.h:150
const std::string & str() const
Definition qcstring.h:537
void reserve(size_t size)
Reserve space for size bytes without changing the string contents.
Definition qcstring.h:172
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
Generator for RTF code fragments.
Definition rtfgen.h:28
void startSpecialComment() override
Definition rtfgen.cpp:202
void endCodeLine() override
Definition rtfgen.cpp:288
void startFontClass(const QCString &) override
Definition rtfgen.cpp:295
size_t m_stripIndentAmount
Definition rtfgen.h:74
void writeCodeLink(CodeSymbolType type, const QCString &ref, const QCString &file, const QCString &anchor, const QCString &name, const QCString &tooltip) override
Definition rtfgen.cpp:118
void endFontClass() override
Definition rtfgen.cpp:320
void endCodeFragment(const QCString &) override
Definition rtfgen.cpp:225
QCString rtf_Code_DepthStyle()
Definition rtfgen.cpp:326
QCString m_sourceFileName
Definition rtfgen.h:70
size_t m_col
Definition rtfgen.h:67
bool m_stripCodeComments
Definition rtfgen.h:72
RTFCodeGenerator(TextStream *t)
Definition rtfgen.cpp:114
void endSpecialComment() override
Definition rtfgen.cpp:207
int m_indentLevel
Definition rtfgen.h:71
bool m_doxyCodeLineOpen
Definition rtfgen.h:69
void stripCodeComments(bool b) override
Definition rtfgen.cpp:197
void setSourceFileName(const QCString &name)
Definition rtfgen.cpp:332
void codify(const QCString &text) override
Definition rtfgen.cpp:153
void startCodeFragment(const QCString &style) override
Definition rtfgen.cpp:217
void writeLineNumber(const QCString &, const QCString &, const QCString &, int l, bool) override
Definition rtfgen.cpp:237
void setStripIndentAmount(size_t amount) override
Definition rtfgen.cpp:212
void startCodeLine(int) override
Definition rtfgen.cpp:281
TextStream * m_t
Definition rtfgen.h:68
Concrete visitor implementation for RTF output.
void startTextBlock(bool dense) override
Definition rtfgen.cpp:2095
void endMemberGroupHeader() override
Definition rtfgen.cpp:2534
void startGroupCollaboration() override
Definition rtfgen.cpp:2361
void endClassDiagram(const ClassDiagram &, const QCString &filename, const QCString &name) override
Definition rtfgen.cpp:1864
void startCallGraph() override
Definition rtfgen.cpp:2369
void endConstraintList() override
Definition rtfgen.cpp:2708
void writeStartAnnoItem(const QCString &type, const QCString &file, const QCString &path, const QCString &name) override
Definition rtfgen.cpp:1441
int m_hierarchyLevel
Definition rtfgen.h:333
void endMemberList() override
Definition rtfgen.cpp:1939
void endConstraintType() override
Definition rtfgen.cpp:2690
void endDescTableRow() override
Definition rtfgen.cpp:1988
void incIndentLevel()
Definition rtfgen.cpp:2038
void startLabels() override
Definition rtfgen.cpp:2827
int m_indentLevel
Definition rtfgen.h:337
void startInlineMemberName() override
Definition rtfgen.cpp:2803
void writeChar(char c) override
Definition rtfgen.cpp:1851
void endDescTableData() override
Definition rtfgen.cpp:2025
void startDescTableData() override
Definition rtfgen.cpp:2019
void endDescTable() override
Definition rtfgen.cpp:1978
OutputType type() const override
Definition rtfgen.h:101
void newParagraph()
Definition rtfgen.cpp:2118
RTFCodeGenerator * m_codeGen
Definition rtfgen.h:346
void endDirDepGraph(DotDirDeps &g) override
Definition rtfgen.cpp:2396
int m_numCols
Definition rtfgen.h:331
static void init()
Definition rtfgen.cpp:461
std::unique_ptr< OutputCodeList > m_codeList
Definition rtfgen.h:345
void startIndexKey() override
Definition rtfgen.cpp:1465
void startConstraintList(const QCString &) override
Definition rtfgen.cpp:2656
void endMemberItem(MemberItemType) override
Definition rtfgen.cpp:1887
void endPlainFile() override
Definition rtfgen.h:307
void startIndexListItem() override
Definition rtfgen.cpp:2717
void endCompoundTemplateParams() override
Definition rtfgen.cpp:1512
void rtfwriteRuler_thick()
Definition rtfgen.cpp:2644
static bool preProcessFileInplace(const QCString &path, const QCString &name)
This is an API to a VERY brittle RTF preprocessor that combines nested RTF files.
Definition rtfgen.cpp:2461
void endBold() override
Definition rtfgen.h:181
static void writeStyleSheetFile(TextStream &t)
Definition rtfgen.cpp:394
void beginRTFChapter()
Definition rtfgen.cpp:663
void endInlineMemberType() override
Definition rtfgen.cpp:2797
void endDescForItem() override
Definition rtfgen.cpp:1801
void startIndent() override
Definition rtfgen.cpp:1762
void lastIndexPage() override
Definition rtfgen.cpp:1316
void endInlineMemberName() override
Definition rtfgen.cpp:2809
void startTextLink(const QCString &f, const QCString &anchor) override
Definition rtfgen.cpp:1518
void endItemList() override
Definition rtfgen.cpp:1380
std::array< RTFListItemInfo, maxIndentLevels > m_listItemInfo
Definition rtfgen.h:344
void startDescTableInit() override
Definition rtfgen.cpp:2005
void writeDoc(const IDocNodeAST *ast, const Definition *, const MemberDef *, int) override
Definition rtfgen.cpp:2621
void endMemberGroup(bool) override
Definition rtfgen.cpp:2560
void writeLabel(const QCString &l, bool isLast) override
Definition rtfgen.cpp:2831
void writeInheritedSectionTitle(const QCString &, const QCString &, const QCString &, const QCString &, const QCString &, const QCString &) override
Definition rtfgen.cpp:2841
void endMemberGroupDocs() override
Definition rtfgen.cpp:2547
void exceptionEntry(const QCString &, bool) override
Definition rtfgen.cpp:2607
void endMemberDocSimple(bool) override
Definition rtfgen.cpp:2785
void startFile(const QCString &name, const QCString &manName, const QCString &title, int id, int hierarchyLevel) override
Definition rtfgen.cpp:704
void startDirDepGraph() override
Definition rtfgen.cpp:2391
void startMemberSubtitle() override
Definition rtfgen.cpp:2143
void startDotGraph() override
Definition rtfgen.cpp:2316
void writePageLink(const QCString &, bool) override
Definition rtfgen.cpp:1308
void endTextBlock(bool) override
Definition rtfgen.cpp:2110
static void writeExtensionsFile(TextStream &t)
Definition rtfgen.cpp:409
void writeString(const QCString &text) override
Definition rtfgen.cpp:1339
void startItemListItem() override
Definition rtfgen.cpp:1390
void endDoxyAnchor(const QCString &, const QCString &) override
Definition rtfgen.cpp:1719
void startBold() override
Definition rtfgen.h:180
void endMemberSubtitle() override
Definition rtfgen.cpp:2150
void startPlainFile(const QCString &name) override
Definition rtfgen.h:306
void startEmphasis() override
Definition rtfgen.h:178
QCString rtf_EList_DepthStyle()
Definition rtfgen.cpp:2083
void startParameterType(bool, const QCString &) override
Definition rtfgen.cpp:2592
void endMemberDoc(bool) override
Definition rtfgen.cpp:1700
void startConstraintDocs() override
Definition rtfgen.cpp:2697
void startDescForItem() override
Definition rtfgen.cpp:1796
void startMemberGroupHeader(const QCString &, bool) override
Definition rtfgen.cpp:2526
void writeRTFReference(const QCString &label)
Definition rtfgen.cpp:1915
void endProjectNumber() override
Definition rtfgen.cpp:733
void startDescTableTitle() override
Definition rtfgen.cpp:1992
void startParameterList(bool) override
Definition rtfgen.cpp:2854
void writeObjectLink(const QCString &ref, const QCString &file, const QCString &anchor, const QCString &name) override
Definition rtfgen.cpp:1583
void endDotGraph(DotClassGraph &) override
Definition rtfgen.cpp:2321
void endIndexItem(const QCString &ref, const QCString &file) override
Definition rtfgen.cpp:1425
void rtfwriteRuler_doubleline()
Definition rtfgen.cpp:2632
void startParagraph(const QCString &classDef) override
Definition rtfgen.cpp:2128
void endIndexSection(IndexSection) override
Definition rtfgen.cpp:927
void endFile() override
Definition rtfgen.cpp:718
void writeNonBreakableSpace(int) override
Definition rtfgen.cpp:1922
void endMemberDescription() override
Definition rtfgen.cpp:1786
bool m_bstartedBody
Definition rtfgen.h:329
void startIndexList() override
Definition rtfgen.cpp:1344
void startIndexItem(const QCString &ref, const QCString &file) override
Definition rtfgen.cpp:1414
void rtfwriteRuler_emboss()
Definition rtfgen.cpp:2638
void addLabel(const QCString &, const QCString &) override
Definition rtfgen.cpp:1741
static const int maxIndentLevels
Definition rtfgen.h:336
void docify(const QCString &text) override
Definition rtfgen.cpp:1844
QCString rtf_BList_DepthStyle()
Definition rtfgen.cpp:2076
QCString rtf_DList_DepthStyle()
Definition rtfgen.cpp:2089
void endSection(const QCString &, SectionType) override
Definition rtfgen.cpp:1834
void endInclDepGraph(DotInclDepGraph &) override
Definition rtfgen.cpp:2344
void startMemberItem(const QCString &, MemberItemType, const QCString &) override
Definition rtfgen.cpp:1881
void endDescTableTitle() override
Definition rtfgen.cpp:1999
void startItemList() override
Definition rtfgen.cpp:1367
void writeAnchor(const QCString &fileName, const QCString &name) override
Definition rtfgen.cpp:1893
void endGroupCollaboration(DotGroupCollaboration &g) override
Definition rtfgen.cpp:2365
void beginRTFDocument()
Definition rtfgen.cpp:526
void endItemListItem() override
Definition rtfgen.cpp:1409
void addCodeGen(OutputCodeList &list) override
Definition rtfgen.cpp:379
void startMemberDocSimple(bool) override
Definition rtfgen.cpp:2744
void startCompoundTemplateParams() override
Definition rtfgen.cpp:1502
void startDescTableRow() override
Definition rtfgen.cpp:1984
void endPageRef(const QCString &, const QCString &) override
Definition rtfgen.cpp:1595
void beginRTFSection()
Definition rtfgen.cpp:683
void startDescTable(const QCString &title, const bool hasInits) override
Definition rtfgen.cpp:1949
void startInlineMemberType() override
Definition rtfgen.cpp:2791
void endParameterExtra(bool, bool, bool) override
Definition rtfgen.cpp:2859
void startPageRef() override
Definition rtfgen.cpp:1589
void startMemberGroup() override
Definition rtfgen.cpp:2554
void rtfwriteRuler_thin()
Definition rtfgen.cpp:2650
void startIndexValue(bool) override
Definition rtfgen.cpp:1476
void startClassDiagram() override
Definition rtfgen.cpp:1859
QCString m_relPath
Definition rtfgen.h:332
bool m_omitParagraph
Definition rtfgen.h:330
void setRelativePath(const QCString &path)
Definition rtfgen.cpp:384
void setSourceFileName(const QCString &sourceFileName)
Definition rtfgen.cpp:389
void endInlineHeader() override
Definition rtfgen.cpp:2736
void startInlineMemberDoc() override
Definition rtfgen.cpp:2815
void addIndexItem(const QCString &, const QCString &) override
Definition rtfgen.cpp:1747
void endIndexList() override
Definition rtfgen.cpp:1354
void endInlineMemberDoc() override
Definition rtfgen.cpp:2821
void endParagraph() override
Definition rtfgen.cpp:2136
void endTextLink() override
Definition rtfgen.cpp:1540
QCString rtf_LCList_DepthStyle()
Definition rtfgen.cpp:2069
void startConstraintType() override
Definition rtfgen.cpp:2684
void startInclDepGraph() override
Definition rtfgen.cpp:2339
void decIndentLevel()
Definition rtfgen.cpp:2050
void endIndexKey() override
Definition rtfgen.cpp:1471
void endTitleHead(const QCString &, const QCString &name) override
Definition rtfgen.cpp:1622
void startMemberGroupDocs() override
Definition rtfgen.cpp:2541
int indentLevel() const
Definition rtfgen.cpp:2033
void endGroupHeader(int) override
Definition rtfgen.cpp:1663
void startExamples() override
Definition rtfgen.cpp:2567
void endCallGraph(DotCallGraph &) override
Definition rtfgen.cpp:2374
void startTitleHead(const QCString &) override
Definition rtfgen.cpp:1612
void endConstraintDocs() override
Definition rtfgen.cpp:2702
void endParameterType() override
Definition rtfgen.cpp:2601
void endIndexValue(const QCString &, bool) override
Definition rtfgen.cpp:1483
void startSection(const QCString &, const QCString &, SectionType) override
Definition rtfgen.cpp:1806
void endEmphasis() override
Definition rtfgen.h:179
void cleanup() override
Definition rtfgen.cpp:519
void endConstraintParam() override
Definition rtfgen.cpp:2677
void startDoxyAnchor(const QCString &, const QCString &, const QCString &, const QCString &, const QCString &) override
Definition rtfgen.cpp:1711
void startProjectNumber() override
Definition rtfgen.cpp:727
void startMemberDoc(const QCString &, const QCString &, const QCString &, const QCString &, int, int, bool) override
Definition rtfgen.cpp:1670
void startIndexSection(IndexSection) override
Definition rtfgen.cpp:738
RTFGenerator & operator=(const RTFGenerator &)
Definition rtfgen.cpp:359
void startInlineHeader() override
Definition rtfgen.cpp:2728
void startMemberList() override
Definition rtfgen.cpp:1928
void endIndent() override
Definition rtfgen.cpp:1770
void writeStyleInfo(int part) override
Definition rtfgen.cpp:1328
void endDescTableInit() override
Definition rtfgen.cpp:2013
void endIndexListItem() override
Definition rtfgen.cpp:2722
void startConstraintParam() override
Definition rtfgen.cpp:2671
void endLabels() override
Definition rtfgen.cpp:2837
void lineBreak(const QCString &style=QCString()) override
Definition rtfgen.cpp:1332
void startGroupHeader(const QCString &, int) override
Definition rtfgen.cpp:1643
void startMemberDescription(const QCString &, const QCString &, bool) override
Definition rtfgen.cpp:1777
QCString rtf_CList_DepthStyle()
Definition rtfgen.cpp:2062
void endExamples() override
Definition rtfgen.cpp:2582
static constexpr int Section
Definition section.h:33
static constexpr int MaxLevel
Definition section.h:39
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 MinLevel
Definition section.h:32
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
void flush()
Flushes the buffer.
Definition textstream.h:209
#define Config_getInt(name)
Definition config.h:34
#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::set< std::string > StringSet
Definition containers.h:31
QCString dateToString(DateTimeType includeTime)
Returns the current date, when includeTime is set also the time is provided.
Definition datetime.cpp:63
std::tm getCurrentDateTime()
Returns the filled in std::tm for the current date and time.
Definition datetime.cpp:30
static QCString objectLinkToString(const QCString &, const QCString &f, const QCString &anchor, const QCString &text)
IDocNodeASTPtr validatingParseText(IDocParser &parserIntf, const QCString &input)
IDocParserPtr createDocParser()
factory function to create a parser
Definition docparser.cpp:55
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 docifyToString(const QCString &str)
Definition mangen.cpp:79
#define err(fmt,...)
Definition message.h:127
#define term(fmt,...)
Definition message.h:137
std::ifstream openInputStream(const QCString &name, bool binary=false, bool openAtEnd=false)
Definition portable.cpp:676
std::ofstream openOutputStream(const QCString &name, bool append=false)
Definition portable.cpp:665
void unlink(const QCString &fileName)
Definition portable.cpp:561
OutputCodeDefer< RTFCodeGenerator > RTFCodeGeneratorDefer
Definition outputlist.h:103
Portable versions of functions that are platform dependent.
int portable_iconv_close(void *cd)
size_t portable_iconv(void *cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft)
void * portable_iconv_open(const char *tocode, const char *fromcode)
#define qsnprintf
Definition qcstring.h:49
const char * qPrint(const char *s)
Definition qcstring.h:672
#define TRUE
Definition qcstring.h:37
#define FALSE
Definition qcstring.h:34
#define ASSERT(x)
Definition qcstring.h:39
#define DBG_RTF(x)
static QCString objectLinkToString(const QCString &ref, const QCString &f, const QCString &anchor, const QCString &text)
Definition rtfgen.cpp:1548
QCString rtfFormatBmkStr(const QCString &name)
Definition rtfgen.cpp:2873
static std::mutex g_rtfFormatMutex
Definition rtfgen.cpp:2869
static QCString dateToRTFDateString()
Definition rtfgen.cpp:59
static StringSet removeSet
Definition rtfgen.cpp:57
void testRTFOutput(const QCString &name)
Tests the integrity of the result by counting brackets.
Definition rtfgen.cpp:2416
static bool preProcessFile(Dir &d, const QCString &infName, TextStream &t, bool bIncludeHeader=true, bool removeFile=true)
VERY brittle routine inline RTF's included by other RTF's.
Definition rtfgen.cpp:2249
static QCString g_nextTag("AAAAAAAAAA")
#define DBG_RTF(x)
Definition rtfgen.cpp:55
static QCString makeIndexName(const QCString &s, int i)
Definition rtfgen.cpp:104
static std::unordered_map< std::string, std::string > g_tagMap
Definition rtfgen.cpp:2870
bool isLeadBytes(int c)
Definition rtfgen.cpp:2157
static void encodeForOutput(TextStream &t, const QCString &s)
Definition rtfgen.cpp:2185
static QCString docifyToString(const QCString &str)
Definition rtfgen.cpp:81
QCString rtfFormatBmkStr(const QCString &name)
Definition rtfgen.cpp:2873
QCString rtf_company
Definition rtfstyle.cpp:26
StyleDataMap rtf_Style
Definition rtfstyle.cpp:362
QCString rtf_documentType
Definition rtfstyle.cpp:30
void loadStylesheet(const QCString &name, StyleDataMap &map)
Definition rtfstyle.cpp:322
Rtf_Style_Default rtf_Style_Default[]
Definition rtfstyle.cpp:88
char rtf_Style_Reset[]
Definition rtfstyle.cpp:49
void loadExtensions(const QCString &name)
Definition rtfstyle.cpp:364
QCString rtf_logoFilename
Definition rtfstyle.cpp:27
QCString rtf_title
Definition rtfstyle.cpp:23
Rtf_Table_Default rtf_Table_Default[]
Definition rtfstyle.cpp:245
QCString rtf_keywords
Definition rtfstyle.cpp:32
QCString rtf_author
Definition rtfstyle.cpp:28
QCString rtf_manager
Definition rtfstyle.cpp:29
QCString rtf_comments
Definition rtfstyle.cpp:25
QCString rtf_subject
Definition rtfstyle.cpp:24
QCString rtf_documentId
Definition rtfstyle.cpp:31
const int rtf_pageWidth
Definition rtfstyle.h:26
const char * name
Definition rtfstyle.h:41
const char * reference
Definition rtfstyle.h:42
const char * definition
Definition rtfstyle.h:43
const char * definition() const
Definition rtfstyle.h:70
const char * reference() const
Definition rtfstyle.h:69
CodeSymbolType
Definition types.h:481
const char * writeUTF8Char(TextStream &t, const char *s)
Writes the UTF8 character pointed to by s to stream t and returns a pointer to the next character.
Definition utf8.cpp:197
Various UTF8 related helper functions.
size_t updateColumnCount(const char *s, size_t col)
Definition util.cpp:7391
QCString stripPath(const QCString &s)
Definition util.cpp:5461
QCString relativePathToRoot(const QCString &name)
Definition util.cpp:4092
void clearSubDirs(const Dir &d)
Definition util.cpp:4180
QCString stripExtensionGeneral(const QCString &fName, const QCString &ext)
Definition util.cpp:5424
void createSubDirs(const Dir &d)
Definition util.cpp:4153
QCString getDotImageExtension()
Definition util.cpp:6800
bool copyFile(const QCString &src, const QCString &dest)
Copies the contents of file with name src to the newly created file with name dest.
Definition util.cpp:6370
A bunch of utility functions.