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