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