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::a3: m_t << "\\paperw16480\\paperh23800"; break;
593 case PAPER_TYPE_t::letter: m_t << "\\paperw12240\\paperh15840"; break;
594 case PAPER_TYPE_t::legal: m_t << "\\paperw12240\\paperh20160"; break;
595 case PAPER_TYPE_t::executive: m_t << "\\paperw10440\\paperh15120"; break;
596 }
597 m_t << "\\margl1800\\margr1800\\margt1440\\margb1440\\gutter0\\ltrsect}\n";
598
599 // sort styles ascending by \s-number via an intermediate QArray
600 unsigned maxIndex = 0;
601 for (const auto &[name,data] : rtf_Style)
602 {
603 uint32_t index = data.index();
604 if (index > maxIndex) maxIndex = index;
605 }
606 std::vector<const StyleData*> array(maxIndex + 1, nullptr);
607 ASSERT(maxIndex < array.size());
608
609 for (const auto &[name,data] : rtf_Style)
610 {
611 uint32_t index = data.index();
612 if (array[index] != nullptr)
613 {
614 err("Style '{}' redefines \\s{}.\n", name, index);
615 }
616 array[index] = &data;
617 }
618
619 // write array elements
620 size_t size = array.size();
621 for(size_t i = 0; i < size; i++)
622 {
623 const StyleData *pStyle = array[i];
624 if (pStyle)
625 {
626 m_t << "{" << pStyle->reference() << pStyle->definition() << ";}\n";
627 }
628 }
629
630 m_t << "}\n";
631
632 // place to write rtf_Table_Default
633 int id = -1;
634 m_t << "{\\*\\listtable" << "\n";
635 for (int i=0 ; rtf_Table_Default[i].definition ; i++ )
636 {
637 if (id != rtf_Table_Default[i].id)
638 {
639 if (id != -1)
640 {
641 m_t << "\\listid" << id << "}" << "\n";
642 }
643 id = rtf_Table_Default[i].id;
644 m_t << "{\\list\\listtemplateid" << rtf_Table_Default[i].id << "\n";
645 }
646 m_t << "{ " << rtf_Table_Default[i].definition << " }" << "\n";
647 }
648 m_t << "\\listid" << id << "}" << "\n";
649 m_t << "}" <<"\n";
650 m_t << "{\\listoverridetable" <<"\n";
651 id = -1;
652 for (int i=0 ; rtf_Table_Default[i].definition ; i++ )
653 {
654 if (id != rtf_Table_Default[i].id)
655 {
656 id = rtf_Table_Default[i].id;
657 m_t << "{\\listoverride\\listid" << id << "\\listoverridecount0\\ls" << id << "}" << "\n";
658 }
659 }
660 m_t << "}" << "\n";
661
662 // this comment is needed for postprocessing!
663 m_t << "{\\comment begin body}\n";
664
665}
666
668{
669 m_t << "\n";
670 DBG_RTF(m_t << "{\\comment BeginRTFChapter}\n")
672
673 // if we are compact, no extra page breaks...
674 if (Config_getBool(COMPACT_RTF))
675 {
676 // m_t << "\\sect\\sectd\\sbknone\n";
677 m_t << "\\sect\\sbknone\n";
679 }
680 else
681 m_t << "\\sect\\sbkpage\n";
682 //m_t << "\\sect\\sectd\\sbkpage\n";
683
684 m_t << rtf_Style["Heading1"].reference() << "\n";
685}
686
688{
689 m_t << "\n";
690 DBG_RTF(m_t << "{\\comment BeginRTFSection}\n")
692
693 // if we are compact, no extra page breaks...
694 if (Config_getBool(COMPACT_RTF))
695 {
696 m_t << "\\sect\\sbknone\n";
698 }
699 else
700 {
701 m_t << "\\sect\\sbkpage\n";
702 }
703 int level = 2 + m_hierarchyLevel;
704
705 m_t << rtf_Style[DString().sprintf("Heading%d", level).str()].reference() << "\n";
706}
707
708void RTFGenerator::startFile(const DString &name,bool,const DString &,const DString &,int,int hierarchyLevel)
709{
710 //setEncoding(DString().sprintf("CP%s",theTranslator->trRTFansicp()));
711 DString fileName=name;
713 m_hierarchyLevel = hierarchyLevel;
714
715 if (!fileName.endsWith(".rtf")) fileName+=".rtf";
720}
721
723{
724 DBG_RTF(m_t << "{\\comment endFile}\n")
725 m_t << "}";
726
727 endPlainFile();
729}
730
732{
733 DBG_RTF(m_t << "{\\comment startProjectNumber }\n")
734 m_t << " ";
735}
736
738{
739 DBG_RTF(m_t << "{\\comment endProjectNumber }\n")
740}
741
743{
744 //DString paperName;
745
746 //m_indentLevel = 0;
747
748 switch (is)
749 {
751 // basic RTFstart
752 // get readyfor author etc
753
754 m_t << "{\\info \n";
755 m_t << "{\\title {\\comment ";
756 break;
758 m_t << "}\n";
759 if (!rtf_subject.empty()) m_t << "{\\subject " << rtf_subject << "}\n";
760 if (!rtf_comments.empty()) m_t << "{\\comment " << rtf_comments << "}\n";
761 if (!rtf_company.empty()) m_t << "{\\company " << rtf_company << "}\n";
762 if (!rtf_author.empty()) m_t << "{\\author " << rtf_author << "}\n";
763 if (!rtf_manager.empty()) m_t << "{\\manager " << rtf_manager << "}\n";
764 if (!rtf_documentType.empty()) m_t << "{\\category " << rtf_documentType << "}\n";
765 if (!rtf_keywords.empty()) m_t << "{\\keywords " << rtf_keywords << "}\n";
766 m_t << "{\\comment ";
767 break;
769 //Introduction
771 break;
773 //Topic Index
775 break;
777 //Module Index
779 break;
781 //Directory Index
783 break;
785 //Namespace Index
787 break;
789 //Concept Index
791 break;
793 //Hierarchical Index
794 DBG_RTF(m_t << "{\\comment start classhierarchy}\n")
796 break;
798 //Annotated Compound Index
800 break;
802 //Annotated File Index
804 break;
806 //Related Page Index
808 break;
810 {
811 //Topic Documentation
812 for (const auto &gd : *Doxygen::groupLinkedMap)
813 {
814 if (!gd->isReference())
815 {
817 break;
818 }
819 }
820 }
821 break;
823 {
824 //Module Documentation
825 for (const auto &mod : ModuleManager::instance().modules())
826 {
827 if (!mod->isReference() && mod->isPrimaryInterface())
828 {
830 break;
831 }
832 }
833 }
834 break;
836 {
837 //Directory Documentation
838 for (const auto &dd : *Doxygen::dirLinkedMap)
839 {
840 if (dd->isLinkableInProject())
841 {
843 break;
844 }
845 }
846 }
847 break;
849 {
850 // Namespace Documentation
851 for (const auto &nd : *Doxygen::namespaceLinkedMap)
852 {
853 if (nd->isLinkableInProject())
854 {
856 break;
857 }
858 }
859 }
860 break;
862 {
863 // Concept Documentation
864 for (const auto &cd : *Doxygen::conceptLinkedMap)
865 {
866 if (cd->isLinkableInProject())
867 {
869 break;
870 }
871 }
872 }
873 break;
875 {
876 //Compound Documentation
877 for (const auto &cd : *Doxygen::classLinkedMap)
878 {
879 if (cd->isLinkableInProject() &&
880 !cd->isImplicitTemplateInstance() &&
881 !cd->isEmbeddedInOuterScope() &&
882 !cd->isAlias()
883 )
884 {
886 break;
887 }
888 }
889 }
890 break;
892 {
893 //File Documentation
894 bool isFirst=true;
895 for (const auto &fn : *Doxygen::inputNameLinkedMap)
896 {
897 for (const auto &fd : *fn)
898 {
899 if (fd->isLinkableInProject() || fd->generateSourceFile())
900 {
901 if (isFirst)
902 {
904 isFirst=false;
905 break;
906 }
907 }
908 }
909 if (!isFirst)
910 {
911 break;
912 }
913 }
914 }
915 break;
917 {
918 //Example Documentation
920 }
921 break;
923 break;
925 break;
927 break;
928 }
929}
930
932{
933 bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN);
934 bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL);
935 DString projectName = Config_getString(PROJECT_NAME);
936
937 switch (is)
938 {
940 if (!rtf_title.empty())
941 // User has overridden document title in extensions file
942 m_t << "}" << rtf_title;
943 else
944 m_t << "}" << projectName;
945 break;
947 {
948 m_t << " doxygen " << getDoxygenVersion() << ".}\n";
950 DBG_RTF(m_t << "{\\comment end of infoblock}\n");
951 // setup for this section
952 m_t << "}";
953 m_t << rtf_Style_Reset <<"\n";
954 m_t << "\\sectd\\pgnlcrm\n";
955 m_t << "{\\footer "<<rtf_Style["Footer"].reference() << "{\\chpgn}}\n";
956 // the title entry
957 DBG_RTF(m_t << "{\\comment begin title page}\n")
958
959
960 m_t << rtf_Style_Reset << rtf_Style["SubTitle"].reference() << "\n"; // set to title style
961
962 m_t << "\\vertalc\\qc\\par\\par\\par\\par\\par\\par\\par\n";
963 if (!rtf_logoFilename.empty())
964 {
965 m_t << "{\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"" << rtf_logoFilename;
966 m_t << "\" \\\\d \\\\*MERGEFORMAT} {\\fldrslt IMAGE }}\\par\\par\n";
967 }
968 if (!rtf_company.empty())
969 {
970 m_t << rtf_company << "\\par\\par\n";
971 }
972
973 m_t << rtf_Style_Reset << rtf_Style["Title"].reference() << "\n"; // set to title style
974 if (!rtf_title.empty())
975 {
976 // User has overridden document title in extensions file
977 m_t << "{\\field\\fldedit {\\*\\fldinst TITLE \\\\*MERGEFORMAT}{\\fldrslt " << rtf_title << "}}\\par\n";
978 }
979 else
980 {
981 auto parser { createDocParser() };
982 auto ast { validatingParseText(*parser.get(), projectName) };
983 if (ast)
984 {
985 m_t << "{\\field\\fldedit {\\*\\fldinst TITLE \\\\*MERGEFORMAT}{\\fldrslt ";
986 writeDoc(ast.get(),nullptr,nullptr,0,-1);
987 m_t << "}}\\par\n";
988 }
989 }
990
991 m_t << rtf_Style_Reset << rtf_Style["SubTitle"].reference() << "\n"; // set to title style
992 m_t << "\\par\n";
993 if (!rtf_documentType.empty())
994 {
995 m_t << rtf_documentType << "\\par\n";
996 }
997 if (!rtf_documentId.empty())
998 {
999 m_t << rtf_documentId << "\\par\n";
1000 }
1001 m_t << "\\par\\par\\par\\par\\par\\par\\par\\par\\par\\par\\par\\par\n";
1002
1003 m_t << rtf_Style_Reset << rtf_Style["SubTitle"].reference() << "\n"; // set to subtitle style
1004 if (!rtf_author.empty())
1005 {
1006 m_t << "{\\field\\fldedit {\\*\\fldinst AUTHOR \\\\*MERGEFORMAT}{\\fldrslt "<< rtf_author << " }}\\par\n";
1007 }
1008 else
1009 {
1010 m_t << "{\\field\\fldedit {\\*\\fldinst AUTHOR \\\\*MERGEFORMAT}{\\fldrslt AUTHOR}}\\par\n";
1011 }
1012
1013 m_t << theTranslator->trVersion() << " " << Config_getString(PROJECT_NUMBER) << "\\par";
1014 switch (Config_getEnum(TIMESTAMP))
1015 {
1016 case TIMESTAMP_t::YES:
1017 case TIMESTAMP_t::DATETIME:
1018 m_t << "{\\field\\fldedit {\\*\\fldinst CREATEDATE \\\\*MERGEFORMAT}"
1019 "{\\fldrslt "<< dateToString(DateTimeType::DateTime) << " }}\\par\n";
1020 break;
1021 case TIMESTAMP_t::DATE:
1022 m_t << "{\\field\\fldedit {\\*\\fldinst CREATEDATE \\\\*MERGEFORMAT}"
1023 "{\\fldrslt "<< dateToString(DateTimeType::Date) << " }}\\par\n";
1024 break;
1025 case TIMESTAMP_t::NO:
1026 break;
1027 }
1028 m_t << "\\page\\page";
1029 DBG_RTF(m_t << "{\\comment End title page}\n")
1030
1031 // table of contents section
1032 DBG_RTF(m_t << "{\\comment Table of contents}\n")
1033 m_t << "\\vertalt\n";
1034 m_t << rtf_Style_Reset << "\n";
1035 m_t << rtf_Style["Heading1"].reference();
1036 m_t << theTranslator->trRTFTableOfContents() << "\\par\n";
1037 m_t << rtf_Style_Reset << "\\par\n";
1038 m_t << "{\\field\\fldedit {\\*\\fldinst TOC \\\\f \\\\*MERGEFORMAT}{\\fldrslt Table of contents}}\\par\n";
1039 m_t << rtf_Style_Reset << "\n";
1040 }
1041 break;
1044 {
1045 writePageLink(Doxygen::mainPage->getOutputFileBase(), true);
1046 }
1047 break;
1049 m_t << "\\par " << rtf_Style_Reset << "\n";
1050 m_t << "{\\tc \\v " << theTranslator->trTopicIndex() << "}\n";
1051 m_t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"topics.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
1052 break;
1054 m_t << "\\par " << rtf_Style_Reset << "\n";
1055 m_t << "{\\tc \\v " << theTranslator->trModuleIndex() << "}\n";
1056 m_t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"modules.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
1057 break;
1059 m_t << "\\par " << rtf_Style_Reset << "\n";
1060 m_t << "{\\tc \\v " << theTranslator->trDirIndex() << "}\n";
1061 m_t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"dirs.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
1062 break;
1064 m_t << "\\par " << rtf_Style_Reset << "\n";
1065 if (fortranOpt)
1066 {
1067 m_t << "{\\tc \\v " << theTranslator->trModulesIndex() << "}\n";
1068 }
1069 else
1070 {
1071 m_t << "{\\tc \\v " << theTranslator->trNamespaceIndex() << "}\n";
1072 }
1073
1074 m_t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"namespaces.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
1075 break;
1077 m_t << "\\par " << rtf_Style_Reset << "\n";
1078 m_t << "{\\tc \\v " << theTranslator->trConceptIndex() << "}\n";
1079 m_t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"concepts.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
1080 break;
1082 m_t << "\\par " << rtf_Style_Reset << "\n";
1083 m_t << "{\\tc \\v " << theTranslator->trHierarchicalIndex() << "}\n";
1084 m_t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"hierarchy.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
1085 break;
1087 m_t << "\\par " << rtf_Style_Reset << "\n";
1088 if (fortranOpt)
1089 {
1090 m_t << "{\\tc \\v " << theTranslator->trCompoundIndexFortran() << "}\n";
1091 }
1092 else if (vhdlOpt)
1093 {
1094 m_t << "{\\tc \\v " << theTranslator->trDesignUnitIndex() << "}\n";
1095 }
1096 else
1097 {
1098 m_t << "{\\tc \\v " << theTranslator->trCompoundIndex() << "}\n";
1099 }
1100 m_t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"annotated.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
1101 break;
1103 m_t << "\\par " << rtf_Style_Reset << "\n";
1104 m_t << "{\\tc \\v " << theTranslator->trFileIndex() << "}\n";
1105 m_t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"files.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
1106 break;
1108 m_t << "\\par " << rtf_Style_Reset << "\n";
1109 m_t << "{\\tc \\v " << theTranslator->trPageIndex() << "}\n";
1110 m_t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"pages.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
1111 break;
1113 {
1114 m_t << "{\\tc \\v " << theTranslator->trTopicDocumentation() << "}\n";
1115 for (const auto &gd : *Doxygen::groupLinkedMap)
1116 {
1117 if (!gd->isReference() && !gd->isASubGroup())
1118 {
1119 writePageLink(gd->getOutputFileBase(), false);
1120 }
1121 }
1122 }
1123 break;
1125 {
1126 m_t << "{\\tc \\v " << theTranslator->trModuleDocumentation() << "}\n";
1127 for (const auto &mod : ModuleManager::instance().modules())
1128 {
1129 if (!mod->isReference() && mod->isPrimaryInterface())
1130 {
1131 writePageLink(mod->getOutputFileBase(), false);
1132 }
1133 }
1134 }
1135 break;
1137 {
1138 bool first=true;
1139 m_t << "{\\tc \\v " << theTranslator->trDirDocumentation() << "}\n";
1140 for (const auto &dd : *Doxygen::dirLinkedMap)
1141 {
1142 if (dd->isLinkableInProject())
1143 {
1144 m_t << "\\par " << rtf_Style_Reset << "\n";
1145 if (!first)
1146 {
1148 }
1149 first=false;
1150 m_t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
1151 m_t << dd->getOutputFileBase();
1152 m_t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
1153 }
1154 }
1155 }
1156 break;
1158 {
1159 bool first=true;
1160 for (const auto &nd : *Doxygen::namespaceLinkedMap)
1161 {
1162 if (nd->isLinkableInProject() && !nd->isAlias())
1163 {
1164 m_t << "\\par " << rtf_Style_Reset << "\n";
1165 if (!first)
1166 {
1168 }
1169 first=false;
1170 m_t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
1171 m_t << nd->getOutputFileBase();
1172 m_t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
1173 }
1174 }
1175 }
1176 break;
1178 {
1179 bool first=true;
1180 for (const auto &cd : *Doxygen::conceptLinkedMap)
1181 {
1182 if (cd->isLinkableInProject() && !cd->isAlias())
1183 {
1184 m_t << "\\par " << rtf_Style_Reset << "\n";
1185 if (!first)
1186 {
1188 }
1189 first=false;
1190 m_t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
1191 m_t << cd->getOutputFileBase();
1192 m_t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
1193 }
1194 }
1195 }
1196 break;
1198 {
1199 bool first=true;
1200 if (fortranOpt)
1201 {
1202 m_t << "{\\tc \\v " << theTranslator->trTypeDocumentation() << "}\n";
1203 }
1204 else
1205 {
1206 m_t << "{\\tc \\v " << theTranslator->trClassDocumentation() << "}\n";
1207 }
1208 for (const auto &cd : *Doxygen::classLinkedMap)
1209 {
1210 if (cd->isLinkableInProject() &&
1211 !cd->isImplicitTemplateInstance() &&
1212 !cd->isEmbeddedInOuterScope() &&
1213 !cd->isAlias()
1214 )
1215 {
1216 m_t << "\\par " << rtf_Style_Reset << "\n";
1217 if (!first)
1218 {
1220 }
1221 first=false;
1222 m_t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
1223 m_t << cd->getOutputFileBase();
1224 m_t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
1225 }
1226 }
1227 }
1228 break;
1230 {
1231 bool isFirst=true;
1232
1233 m_t << "{\\tc \\v " << theTranslator->trFileDocumentation() << "}\n";
1234 for (const auto &fn : *Doxygen::inputNameLinkedMap)
1235 {
1236 for (const auto &fd : *fn)
1237 {
1238 if (fd->isLinkableInProject())
1239 {
1240 m_t << "\\par " << rtf_Style_Reset << "\n";
1241 if (!isFirst)
1242 {
1244 }
1245 isFirst=false;
1246 m_t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
1247 m_t << fd->getOutputFileBase();
1248 m_t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
1249 }
1250 if (fd->generateSourceFile())
1251 {
1252 m_t << "\\par " << rtf_Style_Reset << "\n";
1253 if (!isFirst)
1254 {
1256 }
1257 isFirst=false;
1258 m_t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
1259 m_t << fd->getSourceFileBase();
1260 m_t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
1261 }
1262 }
1263 }
1264 }
1265 break;
1267 {
1268 //m_t << "}\n";
1269 bool isFirst=true;
1270 m_t << "{\\tc \\v " << theTranslator->trExamples() << "}\n";
1271 for (const auto &pd : *Doxygen::exampleLinkedMap)
1272 {
1273 m_t << "\\par " << rtf_Style_Reset << "\n";
1274 if (!isFirst)
1275 {
1277 }
1278 isFirst=false;
1279 m_t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
1280 m_t << pd->getOutputFileBase();
1281 m_t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
1282 }
1283 }
1284 break;
1286 {
1287 m_t << "\\par " << rtf_Style_Reset << "\n";
1288 for (const auto &pd : *Doxygen::pageLinkedMap)
1289 {
1290 if (!pd->getGroupDef() && !pd->isReference() && !pd->hasParentPage()
1291 && Doxygen::mainPage.get() != pd.get())
1292 {
1293 writePageLink(pd->getOutputFileBase(), false);
1294 }
1295 }
1296 }
1297 break;
1299 break;
1302 m_t << rtf_Style["Heading1"].reference();
1303 m_t << theTranslator->trRTFGeneralIndex() << "\\par \n";
1304 m_t << rtf_Style_Reset << "\n";
1305 m_t << "{\\tc \\v " << theTranslator->trRTFGeneralIndex() << "}\n";
1306 m_t << "{\\field\\fldedit {\\*\\fldinst INDEX \\\\c2 \\\\*MERGEFORMAT}{\\fldrslt INDEX}}\n";
1307
1308 break;
1309 }
1310}
1311
1313{
1314 m_t << "\\par " << rtf_Style_Reset << "\n";
1315 m_t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
1316 m_t << name;
1317 m_t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
1318}
1319
1321{
1322 DBG_RTF(m_t << "{\\comment Beginning Body of RTF Document}\n")
1323 // end page and setup for rest of document
1324 m_t << "\\sect \\sbkpage \\pgndec \\pgnrestart\n";
1325 m_t << "\\sect \\sectd \\sbknone\n";
1326
1327 // set new footer with arabic numbers
1328 m_t << "{\\footer "<< rtf_Style["Footer"].reference() << "{\\chpgn}}\n";
1329
1330}
1331
1333{
1334}
1335
1337{
1338 DBG_RTF(m_t << "{\\comment (lineBreak)}" << "\n")
1339 m_t << "\\par\n";
1340 m_omitParagraph = true;
1341}
1342
1344{
1345 m_t << text;
1346}
1347
1349{
1350 DBG_RTF(m_t << "{\\comment (startIndexList)}\n")
1351 m_t << "{\n";
1352 m_t << "\\par\n";
1355 m_omitParagraph = true;
1356}
1357
1359{
1360 DBG_RTF(m_t << "{\\comment (endIndexList)}\n")
1361 if (!m_omitParagraph)
1362 {
1363 m_t << "\\par";
1364 m_omitParagraph = true;
1365 }
1366 m_t << "}";
1368}
1369
1370/*! start bullet list */
1372{
1373 newParagraph();
1375 int level = indentLevel();
1376 DBG_RTF(m_t << "{\\comment (startItemList level=" << level << ") }\n")
1377 m_t << "{";
1378 m_listItemInfo[level].number = 1;
1379 m_listItemInfo[level].isEnum = false;
1380 m_listItemInfo[level].type = '1';
1381}
1382
1383/*! end bullet list */
1385{
1386 newParagraph();
1387 DBG_RTF(m_t << "{\\comment (endItemList level=" << indentLevel() << ")}\n")
1388 m_t << "}";
1390 m_omitParagraph = true;
1391}
1392
1393/*! write bullet or enum item */
1395{
1396 DBG_RTF(m_t << "{\\comment (startItemListItem)}\n")
1397 newParagraph();
1399 int level = indentLevel();
1400 if (m_listItemInfo[level].isEnum)
1401 {
1402 m_t << rtf_EList_DepthStyle() << "\n";
1403 m_t << m_listItemInfo[level].number << ".\\tab ";
1404 m_listItemInfo[level].number++;
1405 }
1406 else
1407 {
1408 m_t << rtf_BList_DepthStyle() << "\n";
1409 }
1410 m_omitParagraph = true;
1411}
1412
1414{
1415 DBG_RTF(m_t << "{\\comment (endItemListItem)}\n")
1416}
1417
1419{
1420 DBG_RTF(m_t << "{\\comment (startIndexItem)}\n")
1421
1422 if (!m_omitParagraph)
1423 {
1424 m_t << "\\par\n";
1425 m_omitParagraph = true;
1426 }
1427}
1428
1430{
1431 DBG_RTF(m_t << "{\\comment (endIndexItem)}\n")
1432 if (ref.empty() && !fn.empty())
1433 {
1434 m_t << "\\tab ";
1436 m_t << "\n";
1437 }
1438 else
1439 {
1440 m_t << "\n";
1441 }
1442 m_omitParagraph = true;
1443}
1444
1446 const DString &path,const DString &name)
1447{
1448 DBG_RTF(m_t << "{\\comment (writeStartAnnoItem)}\n")
1449 m_t << "{\\b ";
1450 if (!path.empty()) docify(path);
1451 if (!f.empty() && Config_getBool(RTF_HYPERLINKS))
1452 {
1453 m_t << "{\\field {\\*\\fldinst { HYPERLINK \\\\l \"";
1455 m_t << "\" }{}";
1456 m_t << "}{\\fldrslt {\\cs37\\ul\\cf2 ";
1457
1458 docify(name);
1459
1460 m_t << "}}}\n";
1461 }
1462 else
1463 {
1464 docify(name);
1465 }
1466 m_t << "} ";
1467}
1468
1470{
1471 DBG_RTF(m_t << "{\\comment (startIndexKey)}\n")
1472 m_t << "{\\b ";
1473}
1474
1476{
1477 DBG_RTF(m_t << "{\\comment (endIndexKey)}\n")
1478}
1479
1481{
1482 DBG_RTF(m_t << "{\\comment (startIndexValue)}\n")
1483 m_t << " ";
1484 if (hasBrief) m_t << "(";
1485}
1486
1487void RTFGenerator::endIndexValue(const DString &name,bool hasBrief)
1488{
1489 DBG_RTF(m_t << "{\\comment (endIndexValue)}\n")
1490 if (hasBrief) m_t << ")";
1491 m_t << "} ";
1492 if (!name.empty())
1493 {
1494 m_t << "\\tab ";
1495 writeRTFReference(name);
1496 m_t << "\n";
1497 }
1498 else
1499 {
1500 m_t << "\n";
1501 }
1502 m_omitParagraph=false;
1503 newParagraph();
1504}
1505
1507{
1508 //beginRTFSubSubSection();
1509 m_t << "\n";
1510 DBG_RTF(m_t << "{\\comment Begin SubSubSection}\n")
1511 m_t << "{\n";
1512 int level = 4 + m_hierarchyLevel;
1513 m_t << rtf_Style_Reset << rtf_Style[DString().sprintf("Heading%d", level).str()].reference() << "\n";
1514}
1515
1517{
1518 newParagraph();
1519 m_t << "}\n";
1520}
1521
1522void RTFGenerator::startTextLink(const DString &f,const DString &anchor)
1523{
1524 if (Config_getBool(RTF_HYPERLINKS))
1525 {
1526 DString ref;
1527 if (!f.empty())
1528 {
1529 ref+=stripPath(f);
1530 }
1531 if (!anchor.empty())
1532 {
1533 ref+='_';
1534 ref+=anchor;
1535 }
1536
1537 m_t << "{\\field {\\*\\fldinst { HYPERLINK \\\\l \"";
1538 m_t << rtfFormatBmkStr(ref);
1539 m_t << "\" }{}";
1540 m_t << "}{\\fldrslt {\\cs37\\ul\\cf2 ";
1541 }
1542}
1543
1545{
1546 if (Config_getBool(RTF_HYPERLINKS))
1547 {
1548 m_t << "}}}\n";
1549 }
1550}
1551
1552static DString objectLinkToString(const DString &ref, const DString &f,
1553 const DString &anchor, const DString &text)
1554{
1555 DString result;
1556 if (ref.empty() && Config_getBool(RTF_HYPERLINKS))
1557 {
1558 DString refName;
1559 if (!f.empty())
1560 {
1561 refName+=stripPath(f);
1562 }
1563 if (!anchor.empty())
1564 {
1565 refName+='_';
1566 refName+=anchor;
1567 }
1568
1569 result += "{\\field {\\*\\fldinst { HYPERLINK \\\\l \"";
1570 result += rtfFormatBmkStr(refName);
1571 result += "\" }{}";
1572 result += "}{\\fldrslt {\\cs37\\ul\\cf2 ";
1573
1574 result += docifyToString(text);
1575
1576 result += "}}}\n";
1577 }
1578 else
1579 {
1580 result += "{\\b ";
1581 result += docifyToString(text);
1582 result += "}";
1583 }
1584 return result;
1585}
1586
1588 const DString &anchor, const DString &text)
1589{
1590 m_t << objectLinkToString(ref,f,anchor,text);
1591}
1592
1594{
1595 m_t << " (";
1596 startEmphasis();
1597}
1598
1599void RTFGenerator::endPageRef(const DString &clname, const DString &anchor)
1600{
1601 DString ref;
1602 if (!clname.empty())
1603 {
1604 ref+=clname;
1605 }
1606 if (!anchor.empty())
1607 {
1608 ref+='_';
1609 ref+=anchor;
1610 }
1611 writeRTFReference(ref);
1612 endEmphasis();
1613 m_t << ")";
1614}
1615
1617{
1618 DBG_RTF(m_t << "{\\comment startTitleHead}\n")
1619 int level = 2 + m_hierarchyLevel;
1620 DString heading;
1621 heading.sprintf("Heading%d", level);
1622 // beginRTFSection();
1623 m_t << rtf_Style_Reset << rtf_Style[heading.str()].reference() << "\n";
1624}
1625
1627{
1628 DBG_RTF(m_t << "{\\comment endTitleHead}\n")
1629 m_t << "\\par " << rtf_Style_Reset << "\n";
1630 if (!name.empty())
1631 {
1632 // make table of contents entry
1633 int level = 2 + m_hierarchyLevel;
1634 m_t << "{\\tc\\tcl" << level << " \\v ";
1635 docify(name);
1636 m_t << "}\n";
1637
1638 // make an index entry
1639 addIndexItem(name,DString());
1640 }
1641 if (!fileName.empty())
1642 {
1644 }
1645}
1646
1647void RTFGenerator::startGroupHeader(const DString &,int extraIndent)
1648{
1649 DBG_RTF(m_t << "{\\comment startGroupHeader}\n")
1651 extraIndent += m_hierarchyLevel;
1652 if (extraIndent>=2)
1653 {
1654 m_t << rtf_Style["Heading5"].reference();
1655 }
1656 else if (extraIndent==1)
1657 {
1658 m_t << rtf_Style["Heading4"].reference();
1659 }
1660 else // extraIndent==0
1661 {
1662 m_t << rtf_Style["Heading3"].reference();
1663 }
1664 m_t << "\n";
1665}
1666
1668{
1669 DBG_RTF(m_t << "{\\comment endGroupHeader}\n")
1670 m_t << "\\par\n";
1671 m_t << rtf_Style_Reset << "\n";
1672}
1673
1675 const DString &memname,
1676 const DString &,
1677 const DString &,
1678 int,
1679 int,
1680 bool showInline)
1681{
1682 DBG_RTF(m_t << "{\\comment startMemberDoc}\n")
1683 if (!memname.empty() && memname[0]!='@')
1684 {
1685 addIndexItem(memname,clname);
1686 addIndexItem(clname,memname);
1687 }
1688
1689 int level = 4 + m_hierarchyLevel;
1690 if (showInline)
1691 ++level;
1692 if (level > 5)
1693 level = 5;
1694 if (level < 1)
1695 level = 1;
1696 m_t << rtf_Style_Reset << rtf_Style[DString().sprintf("Heading%d", level).str()].reference();
1697 //styleStack.push(rtf_Style_Heading4);
1698 m_t << "{\n";
1699 //printf("RTFGenerator::startMemberDoc() '%s'\n",rtf_Style["Heading4"].reference());
1700 startBold();
1701 m_t << "\n";
1702}
1703
1705{
1706 DBG_RTF(m_t << "{\\comment endMemberDoc}\n")
1707 //const DString &style = styleStack.pop();
1708 //printf("RTFGenerator::endMemberDoc() '%s'\n",style);
1709 //ASSERT(style==rtf_Style["Heading4"].reference());
1710 endBold();
1711 m_t << "}\n";
1712 newParagraph();
1713}
1714
1716 const DString &,const DString &,
1717 const DString &
1718 )
1719{
1720 DBG_RTF(m_t << "{\\comment startDoxyAnchor}\n")
1721}
1722
1723void RTFGenerator::endDoxyAnchor(const DString &fName,const DString &anchor)
1724{
1725 DString ref;
1726 if (!fName.empty())
1727 {
1728 ref+=stripPath(fName);
1729 }
1730 if (!anchor.empty())
1731 {
1732 ref+='_';
1733 ref+=anchor;
1734 }
1735
1736 DBG_RTF(m_t << "{\\comment endDoxyAnchor}\n")
1737 m_t << "{\\bkmkstart ";
1738 m_t << rtfFormatBmkStr(ref);
1739 m_t << "}\n";
1740 m_t << "{\\bkmkend ";
1741 m_t << rtfFormatBmkStr(ref);
1742 m_t << "}\n";
1743}
1744
1746{
1747 DBG_RTF(m_t << "{\\comment addLabel}\n")
1748}
1749
1750
1752{
1753 if (!s1.empty())
1754 {
1755 m_t << "{\\xe \\v ";
1756 docify(s1);
1757 if (!s2.empty())
1758 {
1759 m_t << "\\:";
1760 docify(s2);
1761 }
1762 m_t << "}\n";
1763 }
1764}
1765
1767{
1769 DBG_RTF(m_t << "{\\comment (startIndent) }\n")
1770 m_t << "{\n";
1772}
1773
1775{
1776 m_t << "}\n";
1778}
1779
1780
1782{
1783 DBG_RTF(m_t << "{\\comment (startMemberDescription)}\n")
1784 m_t << "{\n";
1787 startEmphasis();
1788}
1789
1791{
1792 DBG_RTF(m_t << "{\\comment (endMemberDescription)}\n")
1793 endEmphasis();
1795 m_t << "\\par";
1796 m_t << "}\n";
1797 m_omitParagraph = true;
1798}
1799
1801{
1802 DBG_RTF(m_t << "{\\comment (startDescForItem) }\n")
1803}
1804
1806{
1807 DBG_RTF(m_t << "{\\comment (endDescForItem) }\n")
1808}
1809
1811{
1812 DBG_RTF(m_t << "{\\comment (startSection)}\n")
1813 m_t << "{";
1815 int num=SectionType::MaxLevel;
1816 switch(type.level())
1817 {
1818 case SectionType::Page: num=2+m_hierarchyLevel; break;
1819 case SectionType::Section: num=3+m_hierarchyLevel; break;
1820 case SectionType::Subsection: // fall through
1821 case SectionType::Subsubsection: // fall through
1822 case SectionType::Paragraph: // fall through
1823 case SectionType::Subparagraph: // fall through
1825 default: ASSERT(0); break;
1826 }
1827 num = std::clamp(num, SectionType::MinLevel, SectionType::MaxLevel);
1828 DString heading;
1829 heading.sprintf("Heading%d",num);
1830 // set style
1831 m_t << rtf_Style[heading.str()].reference();
1832 // make table of contents entry
1833 m_t << "{\\tc\\tcl" << num << " \\v ";
1834 docify(title);
1835 m_t << "}\n";
1836}
1837
1839{
1840 DBG_RTF(m_t << "{\\comment (endSection)}\n")
1841 // make bookmark
1842 m_omitParagraph=false;
1843 newParagraph();
1844 writeAnchor(DString(),lab);
1845 m_t << "}";
1846}
1847
1849{
1850 if (str.empty()) return;
1851 m_t << docifyToString(str);
1852 m_omitParagraph = false;
1853}
1854
1856{
1857 char cs[2];
1858 cs[0]=c;
1859 cs[1]=0;
1860 docify(cs);
1861}
1862
1864{
1865 DBG_RTF(m_t << "{\\comment startClassDiagram }\n")
1866}
1867
1869 const DString &fileName,const DString &)
1870{
1871 newParagraph();
1872
1873 // create a png file
1874 d.writeImage(m_t,dir(),m_relPath,fileName,false,false);
1875
1876 // display the file
1877 m_t << "{\n";
1878 m_t << rtf_Style_Reset << "\n";
1879 m_t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
1880 m_t << fileName << ".png\"";
1881 m_t << " \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par\n";
1882 m_t << "}\n";
1883}
1884
1886{
1887 DBG_RTF(m_t << "{\\comment startMemberItem }\n")
1888 m_t << rtf_Style_Reset << rtf_BList_DepthStyle() << "\n"; // set style to appropriate depth
1889}
1890
1892{
1893 DBG_RTF(m_t << "{\\comment endMemberItem }\n")
1894 newParagraph();
1895}
1896
1898{
1899 DString anchor;
1900 if (!fileName.empty())
1901 {
1902 anchor+=stripPath(fileName);
1903 }
1904 if (!fileName.empty() && !name.empty())
1905 {
1906 anchor+='_';
1907 }
1908 if (!name.empty())
1909 {
1910 anchor+=name;
1911 }
1912 //printf("writeAnchor(%s->%s)\n",qPrint(anchor),qPrint(rtfFormatBmkStr(anchor)));
1913
1914 DBG_RTF(m_t << "{\\comment writeAnchor (" << anchor << ")}\n")
1915 m_t << "{\\bkmkstart " << rtfFormatBmkStr(anchor) << "}\n";
1916 m_t << "{\\bkmkend " << rtfFormatBmkStr(anchor) << "}\n";
1917}
1918
1920{
1921 m_t << "{\\field\\fldedit {\\*\\fldinst PAGEREF ";
1922 m_t << rtfFormatBmkStr(stripPath(label));
1923 m_t << " \\\\*MERGEFORMAT}{\\fldrslt pagenum}}";
1924}
1925
1927{
1928 m_t << "\\~ ";
1929}
1930
1931
1933{
1934 m_t << "\n";
1935 DBG_RTF(m_t << "{\\comment (startMemberList) }\n")
1936 m_t << "{\n";
1937#ifdef DELETEDCODE
1938 if (!insideTabbing)
1939 m_t << "\\begin{CompactItemize}\n";
1940#endif
1941}
1942
1944{
1945 DBG_RTF(m_t << "{\\comment (endMemberList) }\n")
1946 m_t << "}\n";
1947#ifdef DELETEDCODE
1948 if (!insideTabbing)
1949 m_t << "\\end{CompactItemize}\n";
1950#endif
1951}
1952
1953void RTFGenerator::startDescTable(const DString &title,const bool hasInits)
1954{
1955 DBG_RTF(m_t << "{\\comment (startDescTable) }\n")
1956 m_t << "{\\par\n";
1957 m_t << "{" << rtf_Style["Heading5"].reference() << "\n";
1958 docify(title);
1959 m_t << ":\\par}\n";
1961 m_t << "\\trowd \\trgaph108\\trleft426\\tblind426"
1962 "\\trbrdrt\\brdrs\\brdrw10\\brdrcf15 "
1963 "\\trbrdrl\\brdrs\\brdrw10\\brdrcf15 "
1964 "\\trbrdrb\\brdrs\\brdrw10\\brdrcf15 "
1965 "\\trbrdrr\\brdrs\\brdrw10\\brdrcf15 "
1966 "\\trbrdrh\\brdrs\\brdrw10\\brdrcf15 "
1967 "\\trbrdrv\\brdrs\\brdrw10\\brdrcf15 \n";
1968 int columnPos2[2] = { 25, 100 };
1969 int columnPos3[3] = { 25, 45, 100 };
1970 for (int i=0;i<(hasInits?3:2);i++)
1971 {
1972 m_t << "\\clvertalt\\clbrdrt\\brdrs\\brdrw10\\brdrcf15 "
1973 "\\clbrdrl\\brdrs\\brdrw10\\brdrcf15 "
1974 "\\clbrdrb\\brdrs\\brdrw10\\brdrcf15 "
1975 "\\clbrdrr \\brdrs\\brdrw10\\brdrcf15 "
1976 "\\cltxlrtb "
1977 "\\cellx" << (rtf_pageWidth*(hasInits?columnPos3[i]:columnPos2[i])/100) << "\n";
1978 }
1979 m_t << "\\pard \\widctlpar\\intbl\\adjustright\n";
1980}
1981
1983{
1984 DBG_RTF(m_t << "{\\comment (endDescTable)}\n")
1985 m_t << "}\n";
1986}
1987
1991
1995
1997{
1998 DBG_RTF(m_t << "{\\comment (startDescTableTitle) }\n")
1999 m_t << "{";
2000 m_t << rtf_Style["BodyText"].reference();
2001}
2002
2004{
2005 DBG_RTF(m_t << "{\\comment (endDescTableTitle) }\n")
2006 m_t << "\\cell }";
2007}
2008
2010{
2011 DBG_RTF(m_t << "{\\comment (startDescTableInit) }" << endl)
2012 m_t << "{";
2013 m_t << rtf_Style["BodyText"].reference();
2014 m_t << "\\qr ";
2015}
2016
2018{
2019 DBG_RTF(m_t << "{\\comment (endDescTableInit) }" << endl)
2020 m_t << "\\cell }";
2021}
2022
2024{
2025 DBG_RTF(m_t << "{\\comment (startDescTableData) }\n")
2026 m_t << "{";
2027}
2028
2030{
2031 DBG_RTF(m_t << "{\\comment (endDescTableData) }\n")
2032 m_t << "\\cell }{\\row }\n";
2033}
2034
2035// a style for list formatted as a "bulleted list"
2036
2038{
2039 return std::min(m_indentLevel,maxIndentLevels-1);
2040}
2041
2043{
2044 m_indentLevel++;
2046 {
2048 int m = maxIndentLevels;
2049 err("Maximum indent level ({}) exceeded while generating RTF output!\n",m);
2050 }
2052}
2053
2055{
2056 m_indentLevel--;
2057 if (m_indentLevel<0)
2058 {
2059 err("Negative indent level while generating RTF output!\n");
2060 m_indentLevel=0;
2061 }
2063}
2064
2065// a style for list formatted with "list continue" style
2067{
2068 DString n=makeIndexName("ListContinue",indentLevel());
2069 return rtf_Style[n.str()].reference();
2070}
2071
2072// a style for list formatted as a "latext style" table of contents
2074{
2075 DString n=makeIndexName("LatexTOC",indentLevel());
2076 return rtf_Style[n.str()].reference();
2077}
2078
2079// a style for list formatted as a "bullet" style
2081{
2082 DString n=makeIndexName("ListBullet",indentLevel());
2083 return rtf_Style[n.str()].reference();
2084}
2085
2086// a style for list formatted as a "enumeration" style
2088{
2089 DString n=makeIndexName("ListEnum",indentLevel());
2090 return rtf_Style[n.str()].reference();
2091}
2092
2094{
2095 DString n=makeIndexName("DescContinue",indentLevel());
2096 return rtf_Style[n.str()].reference();
2097}
2098
2100{
2101 DBG_RTF(m_t << "{\\comment startTextBlock}\n")
2102 m_t << "{\n";
2104 if (dense) // no spacing between "paragraphs"
2105 {
2106 m_t << rtf_Style["DenseText"].reference();
2107 }
2108 else // some spacing
2109 {
2110 m_t << rtf_Style["BodyText"].reference();
2111 }
2112}
2113
2114void RTFGenerator::endTextBlock(bool /*paraBreak*/)
2115{
2116 newParagraph();
2117 DBG_RTF(m_t << "{\\comment endTextBlock}\n")
2118 m_t << "}\n";
2119 //m_omitParagraph = true;
2120}
2121
2123{
2124 if (!m_omitParagraph)
2125 {
2126 DBG_RTF(m_t << "{\\comment (newParagraph)}\n")
2127 m_t << "\\par\n";
2128 }
2129 m_omitParagraph = false;
2130}
2131
2133{
2134 DBG_RTF(m_t << "{\\comment startParagraph}\n")
2135 newParagraph();
2136 m_t << "{\n";
2137 if (DString(txt) == "reference") m_t << "\\ql\n";
2138}
2139
2141{
2142 DBG_RTF(m_t << "{\\comment endParagraph}\n")
2143 m_t << "}\\par\n";
2144 m_omitParagraph = true;
2145}
2146
2148{
2149 DBG_RTF(m_t << "{\\comment startMemberSubtitle}\n")
2150 m_t << "{\n";
2152}
2153
2155{
2156 DBG_RTF(m_t << "{\\comment endMemberSubtitle}\n")
2157 newParagraph();
2158 m_t << "}\n";
2159}
2160
2161bool isLeadBytes(int c)
2162{
2163 bool result=false; // for SBCS Codepages (cp1252,1251 etc...);
2164
2165 DString codePage = theTranslator->trRTFansicp();
2166
2167 if (codePage == "932") // cp932 (Japanese Shift-JIS)
2168 {
2169 result = (0x81<=c && c<=0x9f) || (0xe0<=c && c<=0xfc);
2170 }
2171 else if (codePage == "936") // cp936 (Simplified Chinese GBK)
2172 {
2173 result = 0x81<=c && c<=0xFE;
2174 }
2175 else if (codePage == "949") // cp949 (Korean)
2176 {
2177 result = 0x81<=c && c<=0xFE;
2178 }
2179 else if (codePage == "950") // cp950 (Traditional Chinese Big5)
2180 {
2181 result = 0x81<=c && c<=0xFE;
2182 }
2183
2184 return result;
2185}
2186
2187
2188// note: function is not reentrant!
2189static void encodeForOutput(TextStream &t,const DString &s)
2190{
2191 if (s==nullptr) return;
2192 DString encoding;
2193 bool converted=false;
2194 size_t l = s.length();
2195 static std::vector<char> enc;
2196 if (l*4>enc.size()) enc.resize(l*4); // worst case
2197 encoding.sprintf("CP%s",qPrint(theTranslator->trRTFansicp()));
2198 if (!encoding.empty())
2199 {
2200 // convert from UTF-8 back to the output encoding
2201 void *cd = portable_iconv_open(encoding.data(),"UTF-8");
2202 if (cd!=reinterpret_cast<void *>(-1))
2203 {
2204 size_t iLeft=l;
2205 size_t oLeft=enc.size();
2206 const char *inputPtr = s.data();
2207 char *outputPtr = &enc[0];
2208 if (!portable_iconv(cd, &inputPtr, &iLeft, &outputPtr, &oLeft))
2209 {
2210 enc.resize(enc.size()-oLeft);
2211 converted=true;
2212 }
2214 }
2215 }
2216 if (!converted) // if we did not convert anything, copy as is.
2217 {
2218 memcpy(enc.data(),s.data(),l);
2219 enc.resize(l);
2220 }
2221 bool multiByte = false;
2222
2223 for (size_t i=0;i<enc.size();i++)
2224 {
2225 uint8_t c = static_cast<uint8_t>(enc.at(i));
2226
2227 if (c>=0x80 || multiByte)
2228 {
2229 char esc[10];
2230 snprintf(esc,10,"\\'%X",c); // escape sequence for SBCS and DBCS(1st&2nd bytes).
2231 t << esc;
2232
2233 if (!multiByte)
2234 {
2235 multiByte = isLeadBytes(c); // It may be DBCS Codepages.
2236 }
2237 else
2238 {
2239 multiByte = false; // end of Double Bytes Character.
2240 }
2241 }
2242 else
2243 {
2244 t << c;
2245 }
2246 }
2247}
2248
2249/**
2250 * VERY brittle routine inline RTF's included by other RTF's.
2251 * it is recursive and ugly.
2252 */
2253static bool preProcessFile(Dir &d,const DString &infName, TextStream &t, bool bIncludeHeader=true, bool removeFile = true)
2254{
2255 static bool rtfDebug = Debug::isFlagSet(Debug::Rtf);
2256 std::ifstream f = Portable::openInputStream(infName);
2257 if (!f.is_open())
2258 {
2259 err("problems opening rtf file '{}' for reading\n",infName);
2260 return false;
2261 }
2262
2263 const int maxLineLength = 10240;
2264 static DString lineBuf(maxLineLength, DString::ExplicitSize);
2265
2266 // scan until find end of header
2267 // this is EXTREEEEEEEMLY brittle. It works on OUR rtf
2268 // files because the first line before the body
2269 // ALWAYS contains "{\comment begin body}"
2270 std::string line;
2271 while (getline(f,line))
2272 {
2273 line+='\n';
2274 if (line.find("\\comment begin body")!=std::string::npos) break;
2275 if (bIncludeHeader) encodeForOutput(t,line);
2276 }
2277
2278 std::string prevLine;
2279 bool first=true;
2280 while (getline(f,line))
2281 {
2282 line+='\n';
2283 size_t pos=prevLine.find("INCLUDETEXT \"");
2284 if (pos!=std::string::npos)
2285 {
2286 size_t startNamePos = prevLine.find('"',pos)+1;
2287 size_t endNamePos = prevLine.find('"',startNamePos);
2288 if (endNamePos != std::string::npos)
2289 {
2290 DString fileName = prevLine.substr(startNamePos,endNamePos-startNamePos);
2291 DBG_RTF(t << "{\\comment begin include " << fileName << "}\n")
2292 if (!preProcessFile(d,fileName,t,false)) return false;
2293 DBG_RTF(t << "{\\comment end include " << fileName << "}\n")
2294 }
2295 }
2296 else if (!first) // no INCLUDETEXT on this line
2297 {
2298 encodeForOutput(t,prevLine);
2299 }
2300 prevLine = line;
2301 first=false;
2302 }
2303 if (!bIncludeHeader) // skip final '}' in case we don't include headers
2304 {
2305 size_t pos = line.rfind('}');
2306 if (pos==std::string::npos)
2307 {
2308 err("Strange, the last char was not a '}}'\n");
2309 pos = line.length();
2310 }
2311 encodeForOutput(t,line.substr(0,pos));
2312 }
2313 else
2314 {
2315 encodeForOutput(t,line);
2316 }
2317 f.close();
2318 // remove temporary file
2319 if (!rtfDebug && removeFile) removeSet.insert(FileInfo(d.filePath(infName.str())).absFilePath());
2320 return true;
2321}
2322
2324{
2325 DBG_RTF(m_t << "{\\comment (startDotGraph)}\n")
2326}
2327
2329{
2330 newParagraph();
2331
2333
2334 // display the file
2335 m_t << "{\n";
2336 m_t << rtf_Style_Reset << "\n";
2337 m_t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
2338 DString imgExt = getDotImageExtension();
2339 m_t << fn << "." << imgExt;
2340 m_t << "\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par\n";
2341 m_t << "}\n";
2342 newParagraph();
2343 DBG_RTF(m_t << "{\\comment (endDotGraph)}\n")
2344}
2345
2347{
2348 DBG_RTF(m_t << "{\\comment (startInclDepGraph)}\n")
2349}
2350
2352{
2353 newParagraph();
2354
2356
2357 // display the file
2358 m_t << "{\n";
2359 m_t << rtf_Style_Reset << "\n";
2360 m_t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
2361 DString imgExt = getDotImageExtension();
2362 m_t << fn << "." << imgExt;
2363 m_t << "\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par\n";
2364 m_t << "}\n";
2365 DBG_RTF(m_t << "{\\comment (endInclDepGraph)}\n")
2366}
2367
2371
2375
2377{
2378 DBG_RTF(m_t << "{\\comment (startCallGraph)}\n")
2379}
2380
2382{
2383 newParagraph();
2384
2386
2387 // display the file
2388 m_t << "{\n";
2389 m_t << rtf_Style_Reset << "\n";
2390 m_t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
2391 DString imgExt = getDotImageExtension();
2392 m_t << fn << "." << imgExt;
2393 m_t << "\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par\n";
2394 m_t << "}\n";
2395 DBG_RTF(m_t << "{\\comment (endCallGraph)}\n")
2396}
2397
2399{
2400 DBG_RTF(m_t << "{\\comment (startDirDepGraph)}\n")
2401}
2402
2404{
2405 newParagraph();
2406
2408
2409 // display the file
2410 m_t << "{\n";
2411 m_t << rtf_Style_Reset << "\n";
2412 m_t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
2413 DString imgExt = getDotImageExtension();
2414 m_t << fn << "." << imgExt;
2415 m_t << "\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par\n";
2416 m_t << "}\n";
2417 DBG_RTF(m_t << "{\\comment (endDirDepGraph)}\n")
2418}
2419
2420/** Tests the integrity of the result by counting brackets.
2421 *
2422 */
2424{
2425 int bcount=0;
2426 int line=1;
2427 int c=0;
2428 std::ifstream f = Portable::openInputStream(name);
2429 if (f.is_open())
2430 {
2431 while ((c=f.get())!=-1)
2432 {
2433 if (c=='\\') // escape char
2434 {
2435 c=f.get();
2436 if (c==-1) break;
2437 }
2438 else if (c=='{') // open bracket
2439 {
2440 bcount++;
2441 }
2442 else if (c=='}') // close bracket
2443 {
2444 bcount--;
2445 if (bcount<0)
2446 {
2447 goto err;
2448 break;
2449 }
2450 }
2451 else if (c=='\n') // newline
2452 {
2453 line++;
2454 }
2455 }
2456 }
2457 if (bcount==0) return; // file is OK.
2458err:
2459 err("RTF integrity test failed at line {:d} of {} due to a bracket mismatch.\n"
2460 " Please try to create a small code example that produces this error \n"
2461 " and send that to doxygen@gmail.com.\n",line,name);
2462}
2463
2464/**
2465 * This is an API to a VERY brittle RTF preprocessor that combines nested
2466 * RTF files. This version replaces the infile with the new file
2467 */
2469{
2470 static bool rtfDebug = Debug::isFlagSet(Debug::Rtf);
2471
2472 Dir d(path.str());
2473 // store the original directory
2474 if (!d.exists())
2475 {
2476 err("Output dir {} does not exist!\n",path);
2477 return false;
2478 }
2479 std::string oldDir = Dir::currentDirPath();
2480
2481 // go to the html output directory (i.e. path)
2483 Dir thisDir;
2484
2485 DString combinedName = path+"/combined.rtf";
2486 DString mainRTFName = path+"/"+name;
2487
2488 std::ofstream f = Portable::openOutputStream(combinedName);
2489 if (!f.is_open())
2490 {
2491 err("Failed to open {} for writing!\n",combinedName);
2492 Dir::setCurrent(oldDir);
2493 return false;
2494 }
2495 TextStream outt(&f);
2496
2497 if (!preProcessFile(thisDir,mainRTFName,outt,true,false))
2498 {
2499 // it failed, remove the temp file
2500 outt.flush();
2501 f.close();
2502 if (!rtfDebug) removeSet.insert(FileInfo(thisDir.filePath(combinedName.str())).absFilePath());
2503 Dir::setCurrent(oldDir);
2504 return false;
2505 }
2506
2507 // everything worked, move the files
2508 outt.flush();
2509 f.close();
2510 if (!rtfDebug)
2511 {
2512 thisDir.remove(mainRTFName.str());
2513 }
2514 else
2515 {
2516 thisDir.rename(mainRTFName.str(),mainRTFName.str() + ".org");
2517 }
2518 thisDir.rename(combinedName.str(),mainRTFName.str());
2519
2520 testRTFOutput(mainRTFName);
2521
2522 DString rtfOutputDir = Dir::currentDirPath();
2523 for (auto &s : removeSet)
2524 {
2525 DString s1 = s;
2526 if (s1.startsWith(rtfOutputDir)) Portable::unlink(s1);
2527 }
2528
2529 Dir::setCurrent(oldDir);
2530 return true;
2531}
2532
2534{
2535 DBG_RTF(m_t << "{\\comment startMemberGroupHeader}\n")
2536 m_t << "{\n";
2537 if (hasHeader) incIndentLevel();
2538 m_t << rtf_Style_Reset << rtf_Style["GroupHeader"].reference();
2539}
2540
2542{
2543 DBG_RTF(m_t << "{\\comment endMemberGroupHeader}\n")
2544 newParagraph();
2546}
2547
2549{
2550 DBG_RTF(m_t << "{\\comment startMemberGroupDocs}\n")
2551 startEmphasis();
2552}
2553
2555{
2556 DBG_RTF(m_t << "{\\comment endMemberGroupDocs}\n")
2557 endEmphasis();
2558 newParagraph();
2559}
2560
2562{
2563 DBG_RTF(m_t << "{\\comment startMemberGroup}\n")
2565}
2566
2568{
2569 DBG_RTF(m_t << "{\\comment endMemberGroup}\n")
2570 if (hasHeader) decIndentLevel();
2571 m_t << "}";
2572}
2573
2575{
2576 DBG_RTF(m_t << "{\\comment (startExamples)}\n")
2577 m_t << "{"; // ends at endDescList
2578 m_t << "{"; // ends at endDescTitle
2579 startBold();
2580 newParagraph();
2582 endBold();
2583 m_t << "}";
2584 newParagraph();
2587}
2588
2590{
2591 DBG_RTF(m_t << "{\\comment (endExamples)}\n")
2592 m_omitParagraph = false;
2593 newParagraph();
2595 m_omitParagraph = true;
2596 m_t << "}";
2597}
2598
2600{
2601 DBG_RTF(m_t << "{\\comment (startParameterType)}\n")
2602 if (!first && !key.empty())
2603 {
2604 m_t << " " << key << " ";
2605 }
2606}
2607
2609{
2610 DBG_RTF(m_t << "{\\comment (endParameterType)}\n")
2611 m_t << " ";
2612}
2613
2614void RTFGenerator::exceptionEntry(const DString &prefix,bool closeBracket)
2615{
2616 DBG_RTF(m_t << "{\\comment (exceptionEntry)}\n")
2617 if (!prefix.empty())
2618 {
2619 m_t << " " << prefix << "(";
2620 }
2621 else if (closeBracket)
2622 {
2623 m_t << ")";
2624 }
2625 m_t << " ";
2626}
2627
2628void RTFGenerator::writeDoc(const IDocNodeAST *ast,const Definition *ctx,const MemberDef *,int,int)
2629{
2630 auto astImpl = dynamic_cast<const DocNodeAST*>(ast);
2631 if (astImpl)
2632 {
2634 std::visit(visitor,astImpl->root);
2635 }
2636 m_omitParagraph = true;
2637}
2638
2640{
2641 DBG_RTF(m_t << "{\\comment (rtfwriteRuler_doubleline)}\n")
2642 m_t << "{\\pard\\widctlpar\\brdrb\\brdrdb\\brdrw15\\brsp20 \\adjustright \\par}\n";
2643}
2644
2646{
2647 DBG_RTF(m_t << "{\\comment (rtfwriteRuler_emboss)}\n")
2648 m_t << "{\\pard\\widctlpar\\brdrb\\brdremboss\\brdrw15\\brsp20 \\adjustright \\par}\n";
2649}
2650
2652{
2653 DBG_RTF(m_t << "{\\comment (rtfwriteRuler_thick)}\n")
2654 m_t << "{\\pard\\widctlpar\\brdrb\\brdrs\\brdrw75\\brsp20 \\adjustright \\par}\n";
2655}
2656
2658{
2659 DBG_RTF(m_t << "{\\comment (rtfwriteRuler_thin)}\n")
2660 m_t << "{\\pard\\widctlpar\\brdrb\\brdrs\\brdrw5\\brsp20 \\adjustright \\par}\n";
2661}
2662
2664{
2665 DBG_RTF(m_t << "{\\comment (startConstraintList)}\n")
2666 m_t << "{"; // ends at endConstraintList
2667 m_t << "{";
2668 startBold();
2669 newParagraph();
2670 docify(header);
2671 endBold();
2672 m_t << "}";
2673 newParagraph();
2676}
2677
2679{
2680 DBG_RTF(m_t << "{\\comment (startConstraintParam)}\n")
2681 startEmphasis();
2682}
2683
2685{
2686 DBG_RTF(m_t << "{\\comment (endConstraintParam)}\n")
2687 endEmphasis();
2688 m_t << " : ";
2689}
2690
2692{
2693 DBG_RTF(m_t << "{\\comment (startConstraintType)}\n")
2694 startEmphasis();
2695}
2696
2698{
2699 DBG_RTF(m_t << "{\\comment (endConstraintType)}\n")
2700 endEmphasis();
2701 m_t << " ";
2702}
2703
2705{
2706 DBG_RTF(m_t << "{\\comment (startConstraintDocs)}\n")
2707}
2708
2710{
2711 DBG_RTF(m_t << "{\\comment (endConstraintDocs)}\n")
2712 newParagraph();
2713}
2714
2716{
2717 DBG_RTF(m_t << "{\\comment (endConstraintList)}\n")
2718 newParagraph();
2720 m_omitParagraph = true;
2721 m_t << "}";
2722}
2723
2725{
2726 DBG_RTF(m_t << "{\\comment (startIndexListItem)}\n")
2727}
2728
2730{
2731 DBG_RTF(m_t << "{\\comment (endIndexListItem)}\n")
2732 m_t << "\\par\n";
2733}
2734
2736{
2737 DBG_RTF(m_t << "{\\comment (startInlineHeader)}\n")
2738 m_t << "{\n";
2739 m_t << rtf_Style_Reset << rtf_Style["Heading5"].reference();
2740 startBold();
2741}
2742
2744{
2745 DBG_RTF(m_t << "{\\comment (endInlineHeader)}\n")
2746 endBold();
2747 m_t << "\\par";
2748 m_t << "}\n";
2749}
2750
2752{
2753 DBG_RTF(m_t << "{\\comment (startMemberDocSimple)}\n")
2754 m_t << "{\\par\n";
2755 m_t << "{" << rtf_Style["Heading5"].reference() << "\n";
2756 if (isEnum)
2757 {
2759 }
2760 else
2761 {
2763 }
2764 m_t << ":\\par}\n";
2766 m_t << "\\trowd \\trgaph108\\trleft426\\tblind426"
2767 "\\trbrdrt\\brdrs\\brdrw10\\brdrcf15 "
2768 "\\trbrdrl\\brdrs\\brdrw10\\brdrcf15 "
2769 "\\trbrdrb\\brdrs\\brdrw10\\brdrcf15 "
2770 "\\trbrdrr\\brdrs\\brdrw10\\brdrcf15 "
2771 "\\trbrdrh\\brdrs\\brdrw10\\brdrcf15 "
2772 "\\trbrdrv\\brdrs\\brdrw10\\brdrcf15 \n";
2773 int n=3,columnPos[3] = { 25, 50, 100 };
2774 if (isEnum)
2775 {
2776 columnPos[0]=30;
2777 columnPos[1]=100;
2778 n=2;
2779 }
2780 for (int i=0;i<n;i++)
2781 {
2782 m_t << "\\clvertalt\\clbrdrt\\brdrs\\brdrw10\\brdrcf15 "
2783 "\\clbrdrl\\brdrs\\brdrw10\\brdrcf15 "
2784 "\\clbrdrb\\brdrs\\brdrw10\\brdrcf15 "
2785 "\\clbrdrr \\brdrs\\brdrw10\\brdrcf15 "
2786 "\\cltxlrtb "
2787 "\\cellx" << (rtf_pageWidth*columnPos[i]/100) << "\n";
2788 }
2789 m_t << "\\pard \\widctlpar\\intbl\\adjustright\n";
2790}
2791
2793{
2794 DBG_RTF(m_t << "{\\comment (endMemberDocSimple)}\n")
2795 m_t << "}\n";
2796}
2797
2799{
2800 DBG_RTF(m_t << "{\\comment (startInlineMemberType)}\n")
2801 m_t << "{\\qr ";
2802}
2803
2805{
2806 DBG_RTF(m_t << "{\\comment (endInlineMemberType)}\n")
2807 m_t << "\\cell }";
2808}
2809
2811{
2812 DBG_RTF(m_t << "{\\comment (startInlineMemberName)}\n")
2813 m_t << "{";
2814}
2815
2817{
2818 DBG_RTF(m_t << "{\\comment (endInlineMemberName)}\n")
2819 m_t << "\\cell }";
2820}
2821
2823{
2824 DBG_RTF(m_t << "{\\comment (startInlineMemberDoc)}\n")
2825 m_t << "{";
2826}
2827
2829{
2830 DBG_RTF(m_t << "{\\comment (endInlineMemberDoc)}\n")
2831 m_t << "\\cell }{\\row }\n";
2832}
2833
2835{
2836}
2837
2838void RTFGenerator::writeLabel(const DString &l,bool isLast)
2839{
2840 m_t << "{\\f2 [" << l << "]}";
2841 if (!isLast) m_t << ", ";
2842}
2843
2845{
2846}
2847
2849 const DString &/*id*/,const DString &ref,
2850 const DString &file, const DString &anchor,
2851 const DString &title, const DString &name)
2852{
2854 m_t << rtf_Style["Heading4"].reference();
2855 m_t << "\n";
2856 m_t << theTranslator->trInheritedFrom(docifyToString(title), objectLinkToString(ref, file, anchor, name));
2857 m_t << "\\par\n";
2858 m_t << rtf_Style_Reset << "\n";
2859}
2860
2862{
2863 if (openBracket) m_t << "(";
2864}
2865
2866void RTFGenerator::endParameterExtra(bool last,bool /* emptyList */, bool closeBracket)
2867{
2868 if (last && closeBracket)
2869 {
2870 m_t << ")";
2871 }
2872}
2873
2874//----------------------------------------------------------------------
2875
2876static std::mutex g_rtfFormatMutex;
2877static std::unordered_map<std::string,std::string> g_tagMap;
2878static DString g_nextTag( "AAAAAAAAAA" );
2879
2881{
2882 std::lock_guard<std::mutex> lock(g_rtfFormatMutex);
2883
2884 // To overcome the 40-character tag limitation, we
2885 // substitute a short arbitrary string for the name
2886 // supplied, and keep track of the correspondence
2887 // between names and strings.
2888 auto it = g_tagMap.find(name.str());
2889 if (it!=g_tagMap.end()) // already known
2890 {
2891 return it->second;
2892 }
2893
2894 DString tag = g_nextTag;
2895 auto result = g_tagMap.emplace(name.str(), g_nextTag.str());
2896
2897 if (result.second) // new item was added
2898 {
2899 // increment the next tag.
2900
2901 char* nxtTag = g_nextTag.rawData() + g_nextTag.length() - 1;
2902 for ( unsigned int i = 0; i < g_nextTag.length(); ++i, --nxtTag )
2903 {
2904 if ( ( ++(*nxtTag) ) > 'Z' )
2905 {
2906 *nxtTag = 'A';
2907 }
2908 else
2909 {
2910 // Since there was no carry, we can stop now
2911 break;
2912 }
2913 }
2914 }
2915
2916 Debug::print(Debug::Rtf,0,"Name = {} RTF_tag = {}\n",name,tag);
2917 return tag;
2918}
2919
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:2099
void startGroupCollaboration() override
Definition rtfgen.cpp:2368
void startCallGraph() override
Definition rtfgen.cpp:2376
void endConstraintList() override
Definition rtfgen.cpp:2715
int m_hierarchyLevel
Definition rtfgen.h:336
void endMemberList() override
Definition rtfgen.cpp:1943
void endConstraintType() override
Definition rtfgen.cpp:2697
void startTextLink(const DString &f, const DString &anchor) override
Definition rtfgen.cpp:1522
void endDescTableRow() override
Definition rtfgen.cpp:1992
void startDescTable(const DString &title, const bool hasInits) override
Definition rtfgen.cpp:1953
void endTitleHead(const DString &, const DString &name) override
Definition rtfgen.cpp:1626
void incIndentLevel()
Definition rtfgen.cpp:2042
void startLabels() override
Definition rtfgen.cpp:2834
void lineBreak(const DString &style=DString()) override
Definition rtfgen.cpp:1336
int m_indentLevel
Definition rtfgen.h:340
void startInlineMemberName() override
Definition rtfgen.cpp:2810
void writeChar(char c) override
Definition rtfgen.cpp:1855
void endDescTableData() override
Definition rtfgen.cpp:2029
void startDescTableData() override
Definition rtfgen.cpp:2023
void endDescTable() override
Definition rtfgen.cpp:1982
size_t m_numCols
Definition rtfgen.h:334
OutputType type() const override
Definition rtfgen.h:101
void newParagraph()
Definition rtfgen.cpp:2122
RTFCodeGenerator * m_codeGen
Definition rtfgen.h:349
void endDirDepGraph(DotDirDeps &g) override
Definition rtfgen.cpp:2403
static void init()
Definition rtfgen.cpp:464
std::unique_ptr< OutputCodeList > m_codeList
Definition rtfgen.h:348
void startIndexKey() override
Definition rtfgen.cpp:1469
void endMemberItem(MemberItemType) override
Definition rtfgen.cpp:1891
void endPlainFile() override
Definition rtfgen.h:307
void startIndexListItem() override
Definition rtfgen.cpp:2724
void endCompoundTemplateParams() override
Definition rtfgen.cpp:1516
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:2468
void rtfwriteRuler_thick()
Definition rtfgen.cpp:2651
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:1445
static void writeStyleSheetFile(TextStream &t)
Definition rtfgen.cpp:397
void beginRTFChapter()
Definition rtfgen.cpp:667
void setRelativePath(const DString &path)
Definition rtfgen.cpp:387
void endInlineMemberType() override
Definition rtfgen.cpp:2804
void startParagraph(const DString &classDef) override
Definition rtfgen.cpp:2132
void endDescForItem() override
Definition rtfgen.cpp:1805
void startIndent() override
Definition rtfgen.cpp:1766
void lastIndexPage() override
Definition rtfgen.cpp:1320
void endInlineMemberName() override
Definition rtfgen.cpp:2816
void endItemList() override
Definition rtfgen.cpp:1384
std::array< RTFListItemInfo, maxIndentLevels > m_listItemInfo
Definition rtfgen.h:347
void startDescTableInit() override
Definition rtfgen.cpp:2009
void endMemberGroup(bool) override
Definition rtfgen.cpp:2567
void startIndexItem(const DString &ref, const DString &file) override
Definition rtfgen.cpp:1418
void endMemberGroupDocs() override
Definition rtfgen.cpp:2554
DString rtf_BList_DepthStyle()
Definition rtfgen.cpp:2080
void addIndexItem(const DString &, const DString &) override
Definition rtfgen.cpp:1751
void startPlainFile(const DString &name) override
Definition rtfgen.h:306
void endMemberDocSimple(bool) override
Definition rtfgen.cpp:2792
void endPageRef(const DString &, const DString &) override
Definition rtfgen.cpp:1599
void startDirDepGraph() override
Definition rtfgen.cpp:2398
void startMemberSubtitle() override
Definition rtfgen.cpp:2147
DString rtf_DList_DepthStyle()
Definition rtfgen.cpp:2093
void startDotGraph() override
Definition rtfgen.cpp:2323
void writeInheritedSectionTitle(const DString &, const DString &, const DString &, const DString &, const DString &, const DString &) override
Definition rtfgen.cpp:2848
void endTextBlock(bool) override
Definition rtfgen.cpp:2114
static void writeExtensionsFile(TextStream &t)
Definition rtfgen.cpp:412
void startItemListItem() override
Definition rtfgen.cpp:1394
void startBold() override
Definition rtfgen.h:180
void endMemberSubtitle() override
Definition rtfgen.cpp:2154
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:1838
void endMemberDoc(bool) override
Definition rtfgen.cpp:1704
void startConstraintDocs() override
Definition rtfgen.cpp:2704
void startDescForItem() override
Definition rtfgen.cpp:1800
DString rtf_LCList_DepthStyle()
Definition rtfgen.cpp:2073
void endProjectNumber() override
Definition rtfgen.cpp:737
void startDescTableTitle() override
Definition rtfgen.cpp:1996
void startParameterList(bool) override
Definition rtfgen.cpp:2861
void startConstraintList(const DString &) override
Definition rtfgen.cpp:2663
void endDotGraph(DotClassGraph &) override
Definition rtfgen.cpp:2328
void rtfwriteRuler_doubleline()
Definition rtfgen.cpp:2639
void writeAnchor(const DString &fileName, const DString &name) override
Definition rtfgen.cpp:1897
void endIndexSection(IndexSection) override
Definition rtfgen.cpp:931
void writeObjectLink(const DString &ref, const DString &file, const DString &anchor, const DString &name) override
Definition rtfgen.cpp:1587
void endFile() override
Definition rtfgen.cpp:722
void writeNonBreakableSpace(int) override
Definition rtfgen.cpp:1926
void endMemberDescription() override
Definition rtfgen.cpp:1790
bool m_bstartedBody
Definition rtfgen.h:332
void exceptionEntry(const DString &, bool) override
Definition rtfgen.cpp:2614
void startIndexList() override
Definition rtfgen.cpp:1348
void startDoxyAnchor(const DString &, const DString &, const DString &, const DString &, const DString &) override
Definition rtfgen.cpp:1715
void rtfwriteRuler_emboss()
Definition rtfgen.cpp:2645
DString m_relPath
Definition rtfgen.h:335
static const int maxIndentLevels
Definition rtfgen.h:339
void startParameterType(bool, const DString &) override
Definition rtfgen.cpp:2599
void endClassDiagram(const ClassDiagram &, const DString &filename, const DString &name) override
Definition rtfgen.cpp:1868
void endInclDepGraph(DotInclDepGraph &) override
Definition rtfgen.cpp:2351
void startMemberDoc(const DString &, const DString &, const DString &, const DString &, int, int, bool) override
Definition rtfgen.cpp:1674
void endDescTableTitle() override
Definition rtfgen.cpp:2003
void startItemList() override
Definition rtfgen.cpp:1371
DString rtf_CList_DepthStyle()
Definition rtfgen.cpp:2066
void endGroupCollaboration(DotGroupCollaboration &g) override
Definition rtfgen.cpp:2372
void beginRTFDocument()
Definition rtfgen.cpp:529
void endItemListItem() override
Definition rtfgen.cpp:1413
void addCodeGen(OutputCodeList &list) override
Definition rtfgen.cpp:382
void writeDoc(const IDocNodeAST *ast, const Definition *, const MemberDef *, int, int) override
Definition rtfgen.cpp:2628
void startMemberDocSimple(bool) override
Definition rtfgen.cpp:2751
void startCompoundTemplateParams() override
Definition rtfgen.cpp:1506
void addLabel(const DString &, const DString &) override
Definition rtfgen.cpp:1745
void startDescTableRow() override
Definition rtfgen.cpp:1988
void beginRTFSection()
Definition rtfgen.cpp:687
void writeLabel(const DString &l, bool isLast) override
Definition rtfgen.cpp:2838
void startInlineMemberType() override
Definition rtfgen.cpp:2798
void endParameterExtra(bool, bool, bool) override
Definition rtfgen.cpp:2866
void startPageRef() override
Definition rtfgen.cpp:1593
void startMemberGroup() override
Definition rtfgen.cpp:2561
void rtfwriteRuler_thin()
Definition rtfgen.cpp:2657
void startIndexValue(bool) override
Definition rtfgen.cpp:1480
void startClassDiagram() override
Definition rtfgen.cpp:1863
void endIndexValue(const DString &, bool) override
Definition rtfgen.cpp:1487
bool m_omitParagraph
Definition rtfgen.h:333
void endIndexItem(const DString &ref, const DString &file) override
Definition rtfgen.cpp:1429
void endInlineHeader() override
Definition rtfgen.cpp:2743
void startInlineMemberDoc() override
Definition rtfgen.cpp:2822
void endIndexList() override
Definition rtfgen.cpp:1358
void endInlineMemberDoc() override
Definition rtfgen.cpp:2828
void endParagraph() override
Definition rtfgen.cpp:2140
void endTextLink() override
Definition rtfgen.cpp:1544
void startConstraintType() override
Definition rtfgen.cpp:2691
void startInclDepGraph() override
Definition rtfgen.cpp:2346
void writeString(const DString &text) override
Definition rtfgen.cpp:1343
void decIndentLevel()
Definition rtfgen.cpp:2054
void endIndexKey() override
Definition rtfgen.cpp:1475
void endMemberGroupHeader(bool) override
Definition rtfgen.cpp:2541
void startMemberGroupDocs() override
Definition rtfgen.cpp:2548
void endDoxyAnchor(const DString &, const DString &) override
Definition rtfgen.cpp:1723
void writePageLink(const DString &, bool) override
Definition rtfgen.cpp:1312
int indentLevel() const
Definition rtfgen.cpp:2037
void endGroupHeader(int) override
Definition rtfgen.cpp:1667
void startMemberItem(const DString &, MemberItemType, const DString &) override
Definition rtfgen.cpp:1885
void startMemberDescription(const DString &, const DString &, bool) override
Definition rtfgen.cpp:1781
void startExamples() override
Definition rtfgen.cpp:2574
void startMemberGroupHeader(const DString &, bool) override
Definition rtfgen.cpp:2533
void startFile(const DString &name, bool isSource, const DString &manName, const DString &title, int id, int hierarchyLevel) override
Definition rtfgen.cpp:708
void endCallGraph(DotCallGraph &) override
Definition rtfgen.cpp:2381
void endConstraintDocs() override
Definition rtfgen.cpp:2709
void endParameterType() override
Definition rtfgen.cpp:2608
void startSection(const DString &, const DString &, SectionType) override
Definition rtfgen.cpp:1810
void endEmphasis() override
Definition rtfgen.h:179
void cleanup() override
Definition rtfgen.cpp:522
void endConstraintParam() override
Definition rtfgen.cpp:2684
void startGroupHeader(const DString &, int) override
Definition rtfgen.cpp:1647
void startProjectNumber() override
Definition rtfgen.cpp:731
void docify(const DString &text) override
Definition rtfgen.cpp:1848
void startIndexSection(IndexSection) override
Definition rtfgen.cpp:742
RTFGenerator & operator=(const RTFGenerator &)
Definition rtfgen.cpp:362
void startInlineHeader() override
Definition rtfgen.cpp:2735
void writeRTFReference(const DString &label)
Definition rtfgen.cpp:1919
void startMemberList() override
Definition rtfgen.cpp:1932
void endIndent() override
Definition rtfgen.cpp:1774
void writeStyleInfo(int part) override
Definition rtfgen.cpp:1332
void endDescTableInit() override
Definition rtfgen.cpp:2017
void endIndexListItem() override
Definition rtfgen.cpp:2729
void startTitleHead(const DString &) override
Definition rtfgen.cpp:1616
void startConstraintParam() override
Definition rtfgen.cpp:2678
DString rtf_EList_DepthStyle()
Definition rtfgen.cpp:2087
void endLabels() override
Definition rtfgen.cpp:2844
void endExamples() override
Definition rtfgen.cpp:2589
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:2880
static void encodeForOutput(TextStream &t, const DString &s)
Definition rtfgen.cpp:2189
static std::mutex g_rtfFormatMutex
Definition rtfgen.cpp:2876
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:1552
static std::unordered_map< std::string, std::string > g_tagMap
Definition rtfgen.cpp:2877
bool isLeadBytes(int c)
Definition rtfgen.cpp:2161
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:2253
static DString dateToRTFDateString()
Definition rtfgen.cpp:62
void testRTFOutput(const DString &name)
Tests the integrity of the result by counting brackets.
Definition rtfgen.cpp:2423
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:2880
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:3946
void clearSubDirs(const Dir &d)
Definition util.cpp:2997
void createSubDirs(const Dir &d)
Definition util.cpp:2970
DString relativePathToRoot(const DString &name)
Definition util.cpp:2913
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:4620
DString getDotImageExtension()
Definition util.cpp:4965
DString stripPath(const DString &s)
Definition util.cpp:3961
A bunch of utility functions.