Doxygen
Loading...
Searching...
No Matches
rtfdocvisitor.cpp
Go to the documentation of this file.
1/******************************************************************************
2 *
3 * Copyright (C) 1997-2022 by Dimitri van Heesch.
4 *
5 * Permission to use, copy, modify, and distribute this software and its
6 * documentation under the terms of the GNU General Public License is hereby
7 * granted. No representations are made about the suitability of this software
8 * for any purpose. It is provided "as is" without express or implied warranty.
9 * See the GNU General Public License for more details.
10 *
11 * Documents produced by Doxygen are derivative works derived from the
12 * input used in their production; they are not affected by this license.
13 *
14 */
15
16#include <algorithm>
17
18#include "rtfdocvisitor.h"
19#include "docparser.h"
20#include "language.h"
21#include "doxygen.h"
22#include "outputgen.h"
23#include "dot.h"
24#include "msc.h"
25#include "util.h"
26#include "rtfstyle.h"
27#include "rtfgen.h"
28#include "message.h"
29#include "parserintf.h"
30#include "msc.h"
31#include "dia.h"
32#include "filedef.h"
33#include "config.h"
34#include "htmlentity.h"
35#include "emoji.h"
36#include "plantuml.h"
37#include "fileinfo.h"
38#include "portable.h"
39#include "codefragment.h"
40
41//#define DBG_RTF(x) m_t << x
42#define DBG_RTF(x) do {} while(0)
43
44static QCString align(const DocHtmlCell &cell)
45{
46 for (const auto &attr : cell.attribs())
47 {
48 if (attr.name.lower()=="align")
49 {
50 if (attr.value.lower()=="center") return "\\qc ";
51 else if (attr.value.lower()=="right") return "\\qr ";
52 else return "";
53 }
54 }
55 return "";
56}
57
58static QCString makeBaseName(const QCString &name)
59{
60 QCString baseName = name;
61 int i = baseName.findRev('/');
62 if (i!=-1)
63 {
64 baseName=baseName.mid(i+1);
65 }
66 return baseName;
67}
68
70 const QCString &langExt, int hierarchyLevel)
71 : m_t(t), m_ci(ci), m_langExt(langExt), m_hierarchyLevel(hierarchyLevel)
72{
73}
74
76{
77 QCString n = name + QCString().setNum(indentLevel());
78 StyleData &sd = rtf_Style[n.str()];
79 return sd.reference();
80}
81
83{
84 for (int i=0 ; rtf_Table_Default[i].definition ; i++ )
85 {
86 if ((id == rtf_Table_Default[i].id) && (m_indentLevel == rtf_Table_Default[i].lvl))
87 {
88 return rtf_Table_Default[i].place;
89 }
90 }
91 ASSERT(0);
92 return "";
93}
94
96{
97 return std::min(m_indentLevel,maxIndentLevels-1);
98}
99
101{
104 {
105 err("Maximum indent level (%d) exceeded while generating RTF output!\n",maxIndentLevels-1);
106 }
107}
108
113
114 //------------------------------------
115 // visitor functions for leaf nodes
116 //--------------------------------------
117
119{
120 if (m_hide) return;
121 DBG_RTF("{\\comment RTFDocVisitor::visit(DocWord)}\n");
122 filter(w.word());
124}
125
127{
128 if (m_hide) return;
129 DBG_RTF("{\\comment RTFDocVisitor::visit(DocLinkedWord)}\n");
130 startLink(w.ref(),w.file(),w.anchor());
131 filter(w.word());
132 endLink(w.ref());
134}
135
137{
138 if (m_hide) return;
139 DBG_RTF("{\\comment RTFDocVisitor::visit(DocWhiteSpace)}\n");
140 if (m_insidePre)
141 {
142 m_t << w.chars();
143 }
144 else
145 {
146 m_t << " ";
147 }
149}
150
152{
153 if (m_hide) return;
154 DBG_RTF("{\\comment RTFDocVisitor::visit(DocSymbol)}\n");
155 const char *res = HtmlEntityMapper::instance().rtf(s.symbol());
156 if (res)
157 {
158 m_t << res;
159 }
160 else
161 {
162 err("RTF: non supported HTML-entity found: %s\n",HtmlEntityMapper::instance().html(s.symbol(),TRUE));
163 }
165}
166
168{
169 if (m_hide) return;
170 DBG_RTF("{\\comment RTFDocVisitor::visit(DocEmoji)}\n");
171 const char *res = EmojiEntityMapper::instance().unicode(s.index());
172 if (res)
173 {
174 const char *p = res;
175 int val = 0;
176 int val1 = 0;
177 while (*p)
178 {
179 switch(*p)
180 {
181 case '&': case '#': case 'x':
182 break;
183 case ';':
184 val1 = val;
185 val = 0xd800 + ( ( val1 - 0x10000 ) & 0xffc00 ) / 0x400 - 0x10000;
186 m_t << "\\u" << val << "?";
187 val = 0xdC00 + ( ( val1 - 0x10000 ) & 0x3ff ) - 0x10000 ;
188 m_t << "\\u" << val << "?";
189 val = 0;
190 break;
191 case '0': case '1': case '2': case '3': case '4':
192 case '5': case '6': case '7': case '8': case '9':
193 val = val * 16 + *p - '0';
194 break;
195 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
196 val = val * 16 + *p - 'a' + 10;
197 break;
198 }
199 p++;
200 }
201 }
202 else
203 {
204 m_t << s.name();
205 }
207}
208
210{
211 if (m_hide) return;
212 DBG_RTF("{\\comment RTFDocVisitor::visit(DocURL)}\n");
213 if (Config_getBool(RTF_HYPERLINKS))
214 {
215 m_t << "{\\field "
216 "{\\*\\fldinst "
217 "{ HYPERLINK \"";
218 if (u.isEmail()) m_t << "mailto:";
219 m_t << u.url();
220 m_t << "\" }"
221 "{}";
222 m_t << "}"
223 "{\\fldrslt "
224 "{\\cs37\\ul\\cf2 ";
225 filter(u.url());
226 m_t << "}"
227 "}"
228 "}\n";
229 }
230 else
231 {
232 m_t << "{\\f2 ";
233 filter(u.url());
234 m_t << "}";
235 }
237}
238
240{
241 if (m_hide) return;
242 DBG_RTF("{\\comment RTFDocVisitor::visit(DocLineBreak)}\n");
243 m_t << "\\par\n";
245}
246
248{
249 if (m_hide) return;
250 DBG_RTF("{\\comment RTFDocVisitor::visit(DocHorRuler)}\n");
251 m_t << "{\\pard\\widctlpar\\brdrb\\brdrs\\brdrw5\\brsp20 \\adjustright \\par}\n";
253}
254
256{
257 if (m_hide) return;
259 DBG_RTF("{\\comment RTFDocVisitor::visit(DocStyleChange)}\n");
260 switch (s.style())
261 {
263 if (s.enable()) m_t << "{\\b "; else m_t << "} ";
264 break;
268 if (s.enable()) m_t << "{\\strike "; else m_t << "} ";
269 break;
272 if (s.enable()) m_t << "{\\ul "; else m_t << "} ";
273 break;
275 if (s.enable()) m_t << "{\\i "; else m_t << "} ";
276 break;
279 if (s.enable()) m_t << "{\\f2 "; else m_t << "} ";
280 break;
282 if (s.enable()) m_t << "{\\sub "; else m_t << "} ";
283 break;
285 if (s.enable()) m_t << "{\\super "; else m_t << "} ";
286 break;
288 if (s.enable()) m_t << "{\\qc "; else m_t << "} ";
289 break;
291 if (s.enable()) m_t << "{\\sub "; else m_t << "} ";
292 break;
294 if (s.enable()) m_t << "{\\i "; else m_t << "} ";
295 break;
297 if (s.enable())
298 {
299 m_t << "{\n";
300 m_t << "\\par\n";
301 m_t << rtf_Style_Reset << getStyle("CodeExample");
303 }
304 else
305 {
307 m_t << "\\par";
308 m_t << "}\n";
309 }
311 break;
312 case DocStyleChange::Div: /* HTML only */ break;
313 case DocStyleChange::Span: /* HTML only */ break;
314 }
315}
316
318{
319 if (m_hide) return;
320 DBG_RTF("{\\comment RTFDocVisitor::visit(DocVerbatim)}\n");
321 QCString lang = m_langExt;
322 if (!s.language().isEmpty()) // explicit language setting
323 {
324 lang = s.language();
325 }
326 SrcLangExt langExt = getLanguageFromCodeLang(lang);
327 switch(s.type())
328 {
330 m_t << "{\n";
331 m_t << "\\par\n";
332 m_t << rtf_Style_Reset << getStyle("CodeExample");
333 getCodeParser(lang).parseCode(m_ci,s.context(),s.text(),langExt,
334 Config_getBool(STRIP_CODE_COMMENTS),
335 s.isExample(),s.exampleFile());
336 //m_t << "\\par\n";
337 m_t << "}\n";
338 break;
340 filter(s.text(),TRUE);
341 break;
343 m_t << "{\n";
344 m_t << "{\\f2 ";
345 filter(s.text(),TRUE);
346 m_t << "}";
347 m_t << "}\n";
348 break;
350 m_t << "{\n";
351 m_t << "\\par\n";
352 m_t << rtf_Style_Reset << getStyle("CodeExample");
353 filter(s.text(),TRUE);
354 //m_t << "\\par\n";
355 m_t << "}\n";
356 break;
358 m_t << s.text();
359 break;
365 /* nothing */
366 break;
367 case DocVerbatim::Dot:
368 {
369 static int dotindex = 1;
370 QCString fileName(4096, QCString::ExplicitSize);
371
372 fileName.sprintf("%s%d%s",
373 qPrint(Config_getString(RTF_OUTPUT)+"/inline_dotgraph_"),
374 dotindex++,
375 ".dot"
376 );
377 std::ofstream file = Portable::openOutputStream(fileName);
378 if (!file.is_open())
379 {
380 err("Could not open file %s for writing\n",qPrint(fileName));
381 }
382 else
383 {
384 QCString stext = s.text();
385 file.write( stext.data(), stext.length() );
386 file.close();
387 }
388
389 writeDotFile(fileName, s.hasCaption(), s.srcFile(), s.srcLine());
390 visitChildren(s);
392
393 if (Config_getBool(DOT_CLEANUP)) Dir().remove(fileName.str());
394 }
395 break;
396 case DocVerbatim::Msc:
397 {
398 static int mscindex = 1;
399 QCString baseName(4096, QCString::ExplicitSize);
400
401 baseName.sprintf("%s%d%s",
402 qPrint(Config_getString(RTF_OUTPUT)+"/inline_mscgraph_"),
403 mscindex++,
404 ".msc"
405 );
406 std::ofstream file = Portable::openOutputStream(baseName);
407 if (!file.is_open())
408 {
409 err("Could not open file %s for writing\n",qPrint(baseName));
410 }
411 QCString text = "msc {";
412 text+=s.text();
413 text+="}";
414 file.write( text.data(), text.length() );
415 file.close();
416
417 writeMscFile(baseName, s.hasCaption(), s.srcFile(), s.srcLine());
418 visitChildren(s);
420
421 if (Config_getBool(DOT_CLEANUP)) Dir().remove(baseName.str());
422 }
423 break;
425 {
426 QCString rtfOutput = Config_getString(RTF_OUTPUT);
429 s.engine(),s.srcFile(),s.srcLine(),true);
430
431 writePlantUMLFile(baseName, s.hasCaption());
432 visitChildren(s);
434 }
435 break;
436 }
438}
439
441{
442 if (m_hide) return;
443 DBG_RTF("{\\comment RTFDocVisitor::visit(DocAnchor)}\n");
444 QCString anchor;
445 if (!anc.file().isEmpty())
446 {
447 anchor+=stripPath(anc.file());
448 }
449 if (!anc.file().isEmpty() && !anc.anchor().isEmpty())
450 {
451 anchor+="_";
452 }
453 if (!anc.anchor().isEmpty())
454 {
455 anchor+=anc.anchor();
456 }
457 m_t << "{\\bkmkstart " << rtfFormatBmkStr(anchor) << "}\n";
458 m_t << "{\\bkmkend " << rtfFormatBmkStr(anchor) << "}\n";
460}
461
463{
464 if (m_hide) return;
466 DBG_RTF("{\\comment RTFDocVisitor::visit(DocInclude)}\n");
467 switch(inc.type())
468 {
470 {
471 m_t << "{\n";
472 m_t << "\\par\n";
473 m_t << rtf_Style_Reset << getStyle("CodeExample");
474 FileInfo cfi( inc.file().str() );
475 auto fd = createFileDef( cfi.dirPath(), cfi.fileName() );
477 inc.text(),
478 langExt,
479 inc.stripCodeComments(),
480 inc.isExample(),
481 inc.exampleFile(),
482 fd.get(), // fileDef,
483 -1, // start line
484 -1, // end line
485 FALSE, // inline fragment
486 nullptr, // memberDef
487 TRUE // show line numbers
488 );
489 m_t << "\\par";
490 m_t << "}\n";
491 }
492 break;
494 m_t << "{\n";
495 m_t << "\\par\n";
496 m_t << rtf_Style_Reset << getStyle("CodeExample");
498 inc.text(),langExt,
499 inc.stripCodeComments(),
500 inc.isExample(),
501 inc.exampleFile(),
502 nullptr, // fileDef
503 -1, // startLine
504 -1, // endLine
505 TRUE, // inlineFragment
506 nullptr, // memberDef
507 FALSE // show line numbers
508 );
509 m_t << "\\par";
510 m_t << "}\n";
511 break;
519 break;
521 m_t << inc.text();
522 break;
524 m_t << "{\n";
525 m_t << "\\par\n";
526 m_t << rtf_Style_Reset << getStyle("CodeExample");
527 filter(inc.text());
528 m_t << "\\par";
529 m_t << "}\n";
530 break;
533 m_t << "{\n";
534 if (!m_lastIsPara) m_t << "\\par\n";
535 m_t << rtf_Style_Reset << getStyle("CodeExample");
537 inc.file(),
538 inc.blockId(),
539 inc.context(),
541 inc.trimLeft(),
543 );
544 m_t << "}";
545 break;
546 }
548}
549
551{
552 //printf("DocIncOperator: type=%d first=%d, last=%d text='%s'\n",
553 // op.type(),op.isFirst(),op.isLast(),qPrint(op.text()));
554 DBG_RTF("{\\comment RTFDocVisitor::visit(DocIncOperator)}\n");
556 if (locLangExt.isEmpty()) locLangExt = m_langExt;
557 SrcLangExt langExt = getLanguageFromFileName(locLangExt);
558 if (op.isFirst())
559 {
560 if (!m_hide)
561 {
562 m_t << "{\n";
563 m_t << "\\par\n";
564 m_t << rtf_Style_Reset << getStyle("CodeExample");
565 }
567 m_hide = TRUE;
568 }
569 if (op.type()!=DocIncOperator::Skip)
570 {
571 m_hide = popHidden();
572 if (!m_hide)
573 {
574 std::unique_ptr<FileDef> fd = nullptr;
575 if (!op.includeFileName().isEmpty())
576 {
577 FileInfo cfi( op.includeFileName().str() );
578 fd = createFileDef( cfi.dirPath(), cfi.fileName() );
579 }
580
581 getCodeParser(locLangExt).parseCode(m_ci,op.context(),op.text(),langExt,
583 op.isExample(),op.exampleFile(),
584 fd.get(), // fileDef
585 op.line(), // startLine
586 -1, // endLine
587 FALSE, // inline fragment
588 nullptr, // memberDef
589 op.showLineNo() // show line numbers
590 );
591 }
593 m_hide=TRUE;
594 }
595 if (op.isLast())
596 {
597 m_hide = popHidden();
598 if (!m_hide)
599 {
600 m_t << "\\par";
601 m_t << "}\n";
602 }
604 }
605 else
606 {
607 if (!m_hide) m_t << "\n";
609 }
610}
611
613{
614 if (m_hide) return;
615 DBG_RTF("{\\comment RTFDocVisitor::visit(DocFormula)}\n");
616 bool bDisplay = !f.isInline();
617 if (bDisplay)
618 {
619 m_t << "\\par";
620 m_t << "{";
621 m_t << "\\pard\\plain";
622 m_t << "\\pard";
623 m_t << "\\qc";
624 }
625 m_t << "{ \\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"" << f.relPath() << f.name() << ".png\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt Image}}";
626 if (bDisplay)
627 {
628 m_t << "\\par}";
629 }
631}
632
634{
635 if (m_hide) return;
636 DBG_RTF("{\\comment RTFDocVisitor::visit(DocIndexEntry)}\n");
637 m_t << "{\\xe \\v " << i.entry() << "}\n";
639}
640
644
646{
647 if (m_hide) return;
648 DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocCite &)}\n");
649 if (!cite.file().isEmpty())
650 {
651 startLink(cite.ref(),cite.file(),cite.anchor());
652 }
653 else
654 {
655 m_t << "{\\b ";
656 }
657 filter(cite.text());
658 if (!cite.file().isEmpty())
659 {
660 endLink(cite.ref());
661 }
662 else
663 {
664 m_t << "}";
665 }
666}
667
668
669//--------------------------------------
670// visitor functions for compound nodes
671//--------------------------------------
672
674{
675 if (m_hide) return;
676 DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocAutoList &)}\n");
677 m_t << "{\n";
678 int level = indentLevel();
679 m_listItemInfo[level].isEnum = l.isEnumList();
680 m_listItemInfo[level].isCheck = l.isCheckedList();
681 m_listItemInfo[level].type = '1';
682 m_listItemInfo[level].number = 1;
684 visitChildren(l);
685 if (!m_lastIsPara) m_t << "\\par";
686 m_t << "}\n";
688 if (!l.isCheckedList() && indentLevel()==0) m_t << "\\par\n";
689}
690
692{
693 static int prevLevel = -1;
694 if (m_hide) return;
695 DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocAutoListItem &)}\n");
696 int level = indentLevel();
697 if ((level != prevLevel-1) &&
698 (!(level==prevLevel && level != 0 && m_listItemInfo[level].isCheck)) &&
699 (!m_lastIsPara))
700 m_t << "\\par\n";
701 prevLevel= level;
703 if (m_listItemInfo[level].isEnum)
704 {
705 m_t << getStyle("ListEnum") << "\n";
706 m_t << m_listItemInfo[level].number << ".\\tab ";
707 m_listItemInfo[level].number++;
708 }
709 else
710 {
711 switch (li.itemNumber())
712 {
713 case DocAutoList::Unchecked: // unchecked
714 m_t << getListTable(2) << "\n";
715 break;
716 case DocAutoList::Checked_x: // checked with x
717 case DocAutoList::Checked_X: // checked with X
718 m_t << getListTable(3) << "\n";
719 break;
720 default:
721 m_t << getListTable(1) << "\n";
722 break;
723 }
724 }
726 m_lastIsPara=false;
727 visitChildren(li);
729}
730
732{
733 if (m_hide) return;
734 DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocPara &)}\n");
735 visitChildren(p);
736 if (!m_lastIsPara &&
737 !p.isLast() && // omit <p> for last paragraph
738 !(p.parent() && // and for parameters & sections
739 std::get_if<DocParamSect>(p.parent())
740 )
741 )
742 {
743 m_t << "\\par\n";
745 }
746}
747
749{
750 if (m_hide) return;
751 DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocRoot &)}\n");
752 if (r.indent()) incIndentLevel();
753 m_t << "{" << rtf_Style["BodyText"].reference() << "\n";
754 visitChildren(r);
755 if (!m_lastIsPara && !r.singleLine()) m_t << "\\par\n";
756 m_t << "}";
758 if (r.indent()) decIndentLevel();
759}
760
762{
763 if (m_hide) return;
764 DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocSimpleSect &)}\n");
765 if (!m_lastIsPara) m_t << "\\par\n";
766 m_t << "{"; // start desc
767 //m_t << "{\\b "; // start bold
768 m_t << "{" << rtf_Style["Heading5"].reference() << "\n";
769 switch(s.type())
770 {
772 m_t << theTranslator->trSeeAlso(); break;
774 m_t << theTranslator->trReturns(); break;
776 m_t << theTranslator->trAuthor(TRUE,TRUE); break;
778 m_t << theTranslator->trAuthor(TRUE,FALSE); break;
780 m_t << theTranslator->trVersion(); break;
782 m_t << theTranslator->trSince(); break;
784 m_t << theTranslator->trDate(); break;
786 m_t << theTranslator->trNote(); break;
788 m_t << theTranslator->trWarning(); break;
790 m_t << theTranslator->trPrecondition(); break;
792 m_t << theTranslator->trPostcondition(); break;
794 m_t << theTranslator->trCopyright(); break;
796 m_t << theTranslator->trInvariant(); break;
798 m_t << theTranslator->trRemarks(); break;
800 m_t << theTranslator->trAttention(); break;
802 m_t << theTranslator->trImportant(); break;
803 case DocSimpleSect::User: break;
804 case DocSimpleSect::Rcs: break;
805 case DocSimpleSect::Unknown: break;
806 }
807
810 {
811 m_t << "\\par";
812 m_t << "}"; // end bold
813 m_t << rtf_Style_Reset << getStyle("DescContinue");
814 m_t << "{\\s17 \\sa60 \\sb30\n";
815 }
816 else
817 {
818 if (s.title())
819 {
820 std::visit(*this,*s.title());
821 }
822 m_t << "\\par\n";
823 m_t << "}"; // end bold
824 m_t << rtf_Style_Reset << getStyle("DescContinue");
825 }
827 visitChildren(s);
828 if (!m_lastIsPara) m_t << "\\par\n";
831 {
832 m_t << "}"; // end DescContinue
833 }
834 m_t << "}"; // end desc
836}
837
839{
840 DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocTitle &)}\n");
841 if (m_hide) return;
842 visitChildren(t);
843}
844
846{
847 if (m_hide) return;
848 DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocSimpleSect &)}\n");
849 m_t << "{\n";
850 m_listItemInfo[indentLevel()].isEnum = false;
851 m_listItemInfo[indentLevel()].isCheck = false;
853 visitChildren(l);
854 if (!m_lastIsPara) m_t << "\\par\n";
855 m_t << "}\n";
857}
858
860{
861 if (m_hide) return;
862 DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocSimpleListItem &)}\n");
863 m_t << "\\par" << rtf_Style_Reset << getStyle("ListBullet") << "\n";
866 if (li.paragraph())
867 {
868 std::visit(*this,*li.paragraph());
869 }
871 DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocSimpleListItem)}\n");
872}
873
875{
876 if (m_hide) return;
877 DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocSection &)}\n");
878 if (!m_lastIsPara) m_t << "\\par\n";
879 m_t << "{\\bkmkstart " << rtfFormatBmkStr(stripPath(s.file())+"_"+s.anchor()) << "}\n";
880 m_t << "{\\bkmkend " << rtfFormatBmkStr(stripPath(s.file())+"_"+s.anchor()) << "}\n";
881 m_t << "{{" // start section
883 QCString heading;
884 int level = std::min(s.level()+2+m_hierarchyLevel,4);
885 if (level <= 0)
886 level = 1;
887 heading.sprintf("Heading%d",level);
888 // set style
889 m_t << rtf_Style[heading.str()].reference() << "\n";
890 // make table of contents entry
891 if (s.title())
892 {
893 std::visit(*this,*s.title());
894 }
895 m_t << "\n\\par" << "}\n";
896 m_t << "{\\tc\\tcl" << level << " \\v ";
897 if (s.title())
898 {
899 std::visit(*this,*s.title());
900 }
901 m_t << "}\n";
903 visitChildren(s);
904 m_t << "\\par}\n"; // end section
906}
907
909{
910 if (m_hide) return;
911 DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocHtmlList &)}\n");
912 m_t << "{\n";
913 int level = indentLevel();
914 m_listItemInfo[level].isEnum = l.type()==DocHtmlList::Ordered;
915 m_listItemInfo[level].isCheck = false;
916 m_listItemInfo[level].number = 1;
917 m_listItemInfo[level].type = '1';
918 for (const auto &opt : l.attribs())
919 {
920 if (opt.name=="type")
921 {
922 m_listItemInfo[level].type = opt.value[0];
923 }
924 if (opt.name=="start")
925 {
926 bool ok = false;
927 int val = opt.value.toInt(&ok);
928 if (ok) m_listItemInfo[level].number = val;
929 }
930 }
932 visitChildren(l);
933 m_t << "\\par" << "}\n";
935}
936
938{
939 if (m_hide) return;
940 DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocHtmlListItem &)}\n");
941 m_t << "\\par\n";
943 int level = indentLevel();
944 if (m_listItemInfo[level].isEnum)
945 {
946 for (const auto &opt : l.attribs())
947 {
948 if (opt.name=="value")
949 {
950 bool ok = false;
951 int val = opt.value.toInt(&ok);
952 if (ok) m_listItemInfo[level].number = val;
953 }
954 }
955 m_t << getStyle("ListEnum") << "\n";
956 switch (m_listItemInfo[level].type)
957 {
958 case '1':
959 m_t << m_listItemInfo[level].number;
960 break;
961 case 'a':
962 m_t << integerToAlpha(m_listItemInfo[level].number,false);
963 break;
964 case 'A':
965 m_t << integerToAlpha(m_listItemInfo[level].number);
966 break;
967 case 'i':
968 m_t << integerToRoman(m_listItemInfo[level].number,false);
969 break;
970 case 'I':
971 m_t << integerToRoman(m_listItemInfo[level].number);
972 break;
973 default:
974 m_t << m_listItemInfo[level].number;
975 break;
976 }
977 m_t << ".\\tab ";
978 m_listItemInfo[level].number++;
979 }
980 else
981 {
982 m_t << getStyle("ListBullet") << "\n";
983 }
986 visitChildren(l);
988 DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlListItem)}\n");
989}
990
992{
993 if (m_hide) return;
994 DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocHtmlDescList &)}\n");
995 //m_t << "{\n";
996 //m_t << rtf_Style_Reset << getStyle("ListContinue");
997 //m_lastIsPara=FALSE;
998 visitChildren(dl);
999 //m_t << "}\n";
1000 //m_t << "\\par\n";
1001 //m_lastIsPara=TRUE;
1002}
1003
1005{
1006 if (m_hide) return;
1007 DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocHtmlDescTitle &)}\n");
1008 //m_t << "\\par\n";
1009 //m_t << "{\\b ";
1010 m_t << "{" << rtf_Style["Heading5"].reference() << "\n";
1012 visitChildren(dt);
1013 m_t << "\\par\n";
1014 m_t << "}\n";
1016}
1017
1019{
1020 if (m_hide) return;
1021 DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocHtmlDescData &)}\n");
1023 m_t << "{" << rtf_Style_Reset << getStyle("DescContinue");
1024 visitChildren(dd);
1025 m_t << "\\par";
1026 m_t << "}\n";
1029}
1030
1032{
1033 if (m_hide) return;
1034 DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocHtmlTable &)}\n");
1035 if (!m_lastIsPara) m_t << "\\par\n";
1037 if (t.caption())
1038 {
1039 const DocHtmlCaption &c = std::get<DocHtmlCaption>(*t.caption());
1040 m_t << "\\pard \\qc \\b";
1041 if (!c.file().isEmpty())
1042 {
1043 m_t << "{\\bkmkstart " << rtfFormatBmkStr(stripPath(c.file())+"_"+c.anchor()) << "}\n";
1044 m_t << "{\\bkmkend " << rtfFormatBmkStr(stripPath(c.file())+"_"+c.anchor()) << "}\n";
1045 }
1046 m_t << "{Table \\field\\flddirty{\\*\\fldinst { SEQ Table \\\\*Arabic }}{\\fldrslt {\\noproof 1}} ";
1047 std::visit(*this,*t.caption());
1048 }
1049 visitChildren(t);
1050 m_t << "\\pard\\plain\n";
1051 m_t << "\\par\n";
1053}
1054
1056{
1057 DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocHtmlCaption &)}\n");
1058 visitChildren(c);
1059 m_t << "}\n\\par\n";
1060}
1061
1063{
1064 if (m_hide) return;
1065 DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocHtmlRow &)}\n");
1066 size_t columnWidth=r.numCells()>0 ? rtf_pageWidth/r.numCells() : 10;
1067 m_t << "\\trowd \\trgaph108\\trleft-108"
1068 "\\trbrdrt\\brdrs\\brdrw10 "
1069 "\\trbrdrl\\brdrs\\brdrw10 "
1070 "\\trbrdrb\\brdrs\\brdrw10 "
1071 "\\trbrdrr\\brdrs\\brdrw10 "
1072 "\\trbrdrh\\brdrs\\brdrw10 "
1073 "\\trbrdrv\\brdrs\\brdrw10 \n";
1074 for (size_t i=0;i<r.numCells();i++)
1075 {
1076 if (r.isHeading())
1077 {
1078 m_t << "\\clcbpat16"; // set cell shading to light grey (color 16 in the clut)
1079 }
1080 m_t << "\\clvertalt\\clbrdrt\\brdrs\\brdrw10 "
1081 "\\clbrdrl\\brdrs\\brdrw10 "
1082 "\\clbrdrb\\brdrs\\brdrw10 "
1083 "\\clbrdrr \\brdrs\\brdrw10 "
1084 "\\cltxlrtb "
1085 "\\cellx" << ((i+1)*columnWidth) << "\n";
1086 }
1087 m_t << "\\pard \\widctlpar\\intbl\\adjustright\n";
1089 visitChildren(r);
1090 m_t << "\n";
1091 m_t << "\\pard \\widctlpar\\intbl\\adjustright\n";
1092 m_t << "{\\row }\n";
1094}
1095
1097{
1098 if (m_hide) return;
1099 DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocHtmlCell &)}\n");
1100 m_t << "{" << align(c);
1102 visitChildren(c);
1103 m_t << "\\cell }";
1105}
1106
1108{
1109 if (m_hide) return;
1110 visitChildren(i);
1111}
1112
1114{
1115 if (m_hide) return;
1116 DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocHRef &)}\n");
1117 if (Config_getBool(RTF_HYPERLINKS))
1118 {
1119 if (href.url().startsWith("#"))
1120 {
1121 // when starting with # so a local link
1122 QCString cite;
1123 cite = href.file() + "_" + href.url().right(href.url().length()-1);
1124 m_t << "{\\field "
1125 "{\\*\\fldinst "
1126 "{ HYPERLINK \\\\l \"" << rtfFormatBmkStr(cite) << "\" "
1127 "}{}"
1128 "}"
1129 "{\\fldrslt "
1130 "{\\cs37\\ul\\cf2 ";
1131 }
1132 else
1133 {
1134 m_t << "{\\field "
1135 "{\\*\\fldinst "
1136 "{ HYPERLINK \"" << href.url() << "\" "
1137 "}{}"
1138 "}"
1139 "{\\fldrslt "
1140 "{\\cs37\\ul\\cf2 ";
1141 }
1142 }
1143 else
1144 {
1145 m_t << "{\\f2 ";
1146 }
1148 visitChildren(href);
1149 if (Config_getBool(RTF_HYPERLINKS))
1150 {
1151 m_t << "}"
1152 "}"
1153 "}";
1154 }
1155 else
1156 {
1157 m_t << "}";
1158 }
1160}
1161
1163{
1164 if (m_hide) return;
1165 m_t << "{\\b ";
1166 visitChildren(s);
1167 m_t << "}\\par ";
1168}
1169
1171{
1172 if (m_hide) return;
1173 DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocHtmlDetails &)}\n");
1174 if (!m_lastIsPara) m_t << "\\par\n";
1175 auto summary = d.summary();
1176 if (summary)
1177 {
1178 std::visit(*this,*summary);
1179 m_t << "{"; // start desc
1181 m_t << rtf_Style_Reset << getStyle("DescContinue");
1182 }
1183 visitChildren(d);
1184 if (!m_lastIsPara) m_t << "\\par\n";
1185 if (summary)
1186 {
1188 m_t << "}"; // end desc
1189 }
1191}
1192
1194{
1195 if (m_hide) return;
1196 DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocHtmlHeader &)}\n");
1197 m_t << "{" // start section
1198 << rtf_Style_Reset;
1199 QCString heading;
1200 int level = std::clamp(header.level()+m_hierarchyLevel,SectionType::MinLevel,SectionType::MaxLevel);
1201 heading.sprintf("Heading%d",level);
1202 // set style
1203 m_t << rtf_Style[heading.str()].reference();
1204 // make open table of contents entry that will be closed in visitPost method
1205 m_t << "{\\tc\\tcl" << level << " ";
1207 visitChildren(header);
1208 // close open table of contents entry
1209 m_t << "} \\par";
1210 m_t << "}\n"; // end section
1212}
1213
1214void RTFDocVisitor::includePicturePreRTF(const QCString &name, bool isTypeRTF, bool hasCaption, bool inlineImage)
1215{
1216 if (isTypeRTF)
1217 {
1218 if (!inlineImage)
1219 {
1220 m_t << "\\par\n";
1221 m_t << "{\n";
1222 m_t << rtf_Style_Reset << "\n";
1223 if (hasCaption || m_lastIsPara) m_t << "\\par\n";
1224 m_t << "\\pard \\qc ";
1225 }
1226 m_t << "{ \\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
1227 m_t << name;
1228 m_t << "\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt Image}}\n";
1229 if (!inlineImage)
1230 {
1231 m_t << "\\par\n";
1232 if (hasCaption)
1233 {
1234 m_t << "\\pard \\qc \\b";
1235 m_t << "{Image \\field\\flddirty{\\*\\fldinst { SEQ Image \\\\*Arabic }}{\\fldrslt {\\noproof 1}} ";
1236 }
1238 }
1239 else
1240 {
1241 if (hasCaption) m_t << "{\\comment "; // to prevent caption to be shown
1242 }
1243 }
1244 else // other format -> skip
1245 {
1247 m_hide=TRUE;
1248 }
1249}
1250
1251void RTFDocVisitor::includePicturePostRTF(bool isTypeRTF, bool hasCaption, bool inlineImage)
1252{
1253 if (isTypeRTF)
1254 {
1255 if (m_hide) return;
1256 if (inlineImage)
1257 {
1258 if (hasCaption) m_t << " }";
1259 }
1260 else
1261 {
1262 if (hasCaption)
1263 {
1264 m_t << "}\n";
1265 m_t << "\\par}\n";
1266 }
1267 else
1268 {
1269 m_t << "}\n";
1270 }
1271 }
1272 }
1273 else
1274 {
1275 m_hide = popHidden();
1276 }
1277}
1278
1280{
1281 DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocImage &)}\n");
1283 visitChildren(img);
1285}
1286
1287
1289{
1290 DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocDotFile &)}\n");
1291 if (!Config_getBool(DOT_CLEANUP)) copyFile(df.file(),Config_getString(RTF_OUTPUT)+"/"+stripPath(df.file()));
1292 writeDotFile(df);
1293 visitChildren(df);
1295}
1297{
1298 DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocMscFile &)}\n");
1299 if (!Config_getBool(DOT_CLEANUP)) copyFile(df.file(),Config_getString(RTF_OUTPUT)+"/"+stripPath(df.file()));
1300 writeMscFile(df);
1301 visitChildren(df);
1303}
1304
1306{
1307 DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocDiaFile &)}\n");
1308 if (!Config_getBool(DOT_CLEANUP)) copyFile(df.file(),Config_getString(RTF_OUTPUT)+"/"+stripPath(df.file()));
1309 writeDiaFile(df);
1310 visitChildren(df);
1312}
1313
1315{
1316 DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocPlantUmlFile &)}\n");
1317 if (!Config_getBool(DOT_CLEANUP)) copyFile(df.file(),Config_getString(RTF_OUTPUT)+"/"+stripPath(df.file()));
1318 QCString rtfOutput = Config_getString(RTF_OUTPUT);
1319 std::string inBuf;
1320 readInputFile(df.file(),inBuf);
1322 rtfOutput,QCString(),inBuf.c_str(),PlantumlManager::PUML_BITMAP,
1323 QCString(),df.srcFile(),df.srcLine(),false);
1324 writePlantUMLFile(baseName, df.hasCaption());
1325 visitChildren(df);
1327}
1328
1330{
1331 if (m_hide) return;
1332 DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocLink &)}\n");
1333 startLink(lnk.ref(),lnk.file(),lnk.anchor());
1334 visitChildren(lnk);
1335 endLink(lnk.ref());
1336}
1337
1339{
1340 if (m_hide) return;
1341 DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocRef &)}\n");
1342 // when ref.isSubPage()==TRUE we use ref.file() for HTML and
1343 // ref.anchor() for LaTeX/RTF
1344 if (ref.isSubPage())
1345 {
1346 startLink(ref.ref(),QCString(),ref.anchor());
1347 }
1348 else
1349 {
1350 if (!ref.file().isEmpty()) startLink(ref.ref(),ref.file(),ref.anchor());
1351 }
1352 if (!ref.hasLinkText()) filter(ref.targetTitle());
1353 visitChildren(ref);
1354 if (!ref.file().isEmpty()) endLink(ref.ref());
1355 //m_t << " ";
1356}
1357
1358
1360{
1361 DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocSecRefItem &)}\n");
1362 visitChildren(ref);
1363}
1364
1366{
1367 if (m_hide) return;
1368 DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocSecRefList &)}\n");
1369 m_t << "{\n";
1371 m_t << rtf_Style_Reset << getStyle("LatexTOC") << "\n";
1372 m_t << "\\par\n";
1374 visitChildren(l);
1376 m_t << "\\par";
1377 m_t << "}\n";
1379}
1380
1382{
1383 if (m_hide) return;
1384 DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocParamSect &)}\n");
1385 m_t << "{"; // start param list
1386 if (!m_lastIsPara) m_t << "\\par\n";
1387 //m_t << "{\\b "; // start bold
1388 m_t << "{" << rtf_Style["Heading5"].reference() << "\n";
1389 switch(s.type())
1390 {
1392 m_t << theTranslator->trParameters(); break;
1394 m_t << theTranslator->trReturnValues(); break;
1396 m_t << theTranslator->trExceptions(); break;
1398 m_t << theTranslator->trTemplateParameters(); break;
1399 default:
1400 ASSERT(0);
1401 }
1402 m_t << "\\par";
1403 m_t << "}\n";
1404 bool useTable = s.type()==DocParamSect::Param ||
1408 if (!useTable)
1409 {
1411 }
1412 m_t << rtf_Style_Reset << getStyle("DescContinue");
1414 visitChildren(s);
1415 //m_t << "\\par\n";
1416 if (!useTable)
1417 {
1419 }
1420 m_t << "}\n";
1421}
1422
1424{
1425 m_t << " " << sep.chars() << " ";
1426}
1427
1429{
1430 static int columnPos[4][5] =
1431 { { 2, 25, 100, 100, 100 }, // no inout, no type
1432 { 3, 14, 35, 100, 100 }, // inout, no type
1433 { 3, 25, 50, 100, 100 }, // no inout, type
1434 { 4, 14, 35, 55, 100 }, // inout, type
1435 };
1436 int config=0;
1437 if (m_hide) return;
1438 DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocParamList &)}\n");
1439
1441 const DocParamSect *sect = std::get_if<DocParamSect>(pl.parent());
1442 if (sect)
1443 {
1444 parentType = sect->type();
1445 }
1446 bool useTable = parentType==DocParamSect::Param ||
1447 parentType==DocParamSect::RetVal ||
1448 parentType==DocParamSect::Exception ||
1449 parentType==DocParamSect::TemplateParam;
1450 if (sect && sect->hasInOutSpecifier()) config+=1;
1451 if (sect && sect->hasTypeSpecifier()) config+=2;
1452 if (useTable)
1453 {
1454 m_t << "\\trowd \\trgaph108\\trleft426\\tblind426"
1455 "\\trbrdrt\\brdrs\\brdrw10\\brdrcf15 "
1456 "\\trbrdrl\\brdrs\\brdrw10\\brdrcf15 "
1457 "\\trbrdrb\\brdrs\\brdrw10\\brdrcf15 "
1458 "\\trbrdrr\\brdrs\\brdrw10\\brdrcf15 "
1459 "\\trbrdrh\\brdrs\\brdrw10\\brdrcf15 "
1460 "\\trbrdrv\\brdrs\\brdrw10\\brdrcf15 "<< "\n";
1461 for (int i=0;i<columnPos[config][0];i++)
1462 {
1463 m_t << "\\clvertalt\\clbrdrt\\brdrs\\brdrw10\\brdrcf15 "
1464 "\\clbrdrl\\brdrs\\brdrw10\\brdrcf15 "
1465 "\\clbrdrb\\brdrs\\brdrw10\\brdrcf15 "
1466 "\\clbrdrr \\brdrs\\brdrw10\\brdrcf15 "
1467 "\\cltxlrtb "
1468 "\\cellx" << (rtf_pageWidth*columnPos[config][i+1]/100) << "\n";
1469 }
1470 m_t << "\\pard \\widctlpar\\intbl\\adjustright\n";
1471 }
1472
1473 if (sect && sect->hasInOutSpecifier())
1474 {
1475 if (useTable)
1476 {
1477 m_t << "{";
1478 }
1479
1480 // Put in the direction: in/out/in,out if specified.
1482 {
1483 if (pl.direction()==DocParamSect::In)
1484 {
1485 m_t << "in";
1486 }
1487 else if (pl.direction()==DocParamSect::Out)
1488 {
1489 m_t << "out";
1490 }
1491 else if (pl.direction()==DocParamSect::InOut)
1492 {
1493 m_t << "in,out";
1494 }
1495 }
1496
1497 if (useTable)
1498 {
1499 m_t << "\\cell }";
1500 }
1501 }
1502
1503 if (sect && sect->hasTypeSpecifier())
1504 {
1505 if (useTable)
1506 {
1507 m_t << "{";
1508 }
1509 for (const auto &type : pl.paramTypes())
1510 {
1511 std::visit(*this,type);
1512 }
1513 if (useTable)
1514 {
1515 m_t << "\\cell }";
1516 }
1517 }
1518
1519
1520 if (useTable)
1521 {
1522 m_t << "{";
1523 }
1524
1525 m_t << "{\\i ";
1526 bool first=TRUE;
1527 for (const auto &param : pl.parameters())
1528 {
1529 if (!first) m_t << ","; else first=FALSE;
1530 std::visit(*this,param);
1531 }
1532 m_t << "} ";
1533
1534 if (useTable)
1535 {
1536 m_t << "\\cell }{";
1537 }
1539
1540 for (const auto &par : pl.paragraphs())
1541 {
1542 std::visit(*this,par);
1543 }
1544
1545 if (useTable)
1546 {
1547 m_t << "\\cell }\n";
1548 //m_t << "\\pard \\widctlpar\\intbl\\adjustright\n";
1549 m_t << "{\\row }\n";
1550 }
1551 else
1552 {
1553 m_t << "\\par\n";
1554 }
1555
1557}
1558
1560{
1561 if (m_hide) return;
1562 if (x.title().isEmpty()) return;
1563 bool anonymousEnum = x.file()=="@";
1564 DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocXRefItem &)}\n");
1565 if (!m_lastIsPara)
1566 {
1567 m_t << "\\par\n";
1569 }
1570 m_t << "{"; // start param list
1571 //m_t << "{\\b "; // start bold
1572 m_t << "{" << rtf_Style["Heading5"].reference() << "\n";
1573 if (Config_getBool(RTF_HYPERLINKS) && !anonymousEnum)
1574 {
1575 QCString refName;
1576 if (!x.file().isEmpty())
1577 {
1578 refName+=stripPath(x.file());
1579 }
1580 if (!x.file().isEmpty() && !x.anchor().isEmpty())
1581 {
1582 refName+="_";
1583 }
1584 if (!x.anchor().isEmpty())
1585 {
1586 refName+=x.anchor();
1587 }
1588
1589 m_t << "{\\field "
1590 "{\\*\\fldinst "
1591 "{ HYPERLINK \\\\l \"" << rtfFormatBmkStr(refName) << "\" "
1592 "}{}"
1593 "}"
1594 "{\\fldrslt "
1595 "{\\cs37\\ul\\cf2 ";
1596 filter(x.title());
1597 m_t << "}"
1598 "}"
1599 "}";
1600 }
1601 else
1602 {
1603 filter(x.title());
1604 }
1605 m_t << ":";
1606 m_t << "\\par";
1607 m_t << "}"; // end bold
1609 m_t << rtf_Style_Reset << getStyle("DescContinue");
1611 visitChildren(x);
1612 if (x.title().isEmpty()) return;
1613 DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocXRefItem)}\n");
1614 m_t << "\\par\n";
1616 m_t << "}\n"; // end xref item
1618}
1619
1621{
1622 if (m_hide) return;
1623 DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocInternalRef &)}\n");
1624 startLink("",ref.file(),ref.anchor());
1625 visitChildren(ref);
1626 endLink("");
1627 m_t << " ";
1628}
1629
1631{
1632 if (m_hide) return;
1633 DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocText &)}\n");
1634 visitChildren(t);
1635}
1636
1638{
1639 if (m_hide) return;
1640 DBG_RTF("{\\comment RTFDocVisitor::operator()(const DocHtmlBlockQuote &)}\n");
1641 if (!m_lastIsPara) m_t << "\\par\n";
1642 m_t << "{"; // start desc
1644 m_t << rtf_Style_Reset << getStyle("DescContinue");
1645 visitChildren(q);
1646 if (!m_lastIsPara) m_t << "\\par\n";
1648 m_t << "}"; // end desc
1650}
1651
1653{
1654}
1655
1657{
1658 if (m_hide) return;
1659 visitChildren(pb);
1660}
1661
1662
1663//static char* getMultiByte(int c)
1664//{
1665// static char s[10];
1666// sprintf(s,"\\'%X",c);
1667// return s;
1668//}
1669
1670void RTFDocVisitor::filter(const QCString &str,bool verbatim)
1671{
1672 if (!str.isEmpty())
1673 {
1674 const char *p=str.data();
1675 while (*p)
1676 {
1677 char c=*p++;
1678 switch (c)
1679 {
1680 case '{': m_t << "\\{"; break;
1681 case '}': m_t << "\\}"; break;
1682 case '\\': m_t << "\\\\"; break;
1683 case '\n': if (verbatim)
1684 {
1685 m_t << "\\par\n";
1686 }
1687 else
1688 {
1689 m_t << '\n';
1690 }
1691 break;
1692 default: m_t << c;
1693 }
1694 }
1695 }
1696}
1697
1698void RTFDocVisitor::startLink(const QCString &ref,const QCString &file,const QCString &anchor)
1699{
1700 if (ref.isEmpty() && Config_getBool(RTF_HYPERLINKS))
1701 {
1702 QCString refName;
1703 if (!file.isEmpty())
1704 {
1705 refName+=stripPath(file);
1706 }
1707 if (!file.isEmpty() && !anchor.isEmpty())
1708 {
1709 refName+='_';
1710 }
1711 if (!anchor.isEmpty())
1712 {
1713 refName+=anchor;
1714 }
1715
1716 m_t << "{\\field {\\*\\fldinst { HYPERLINK \\\\l \"";
1717 m_t << rtfFormatBmkStr(refName);
1718 m_t << "\" }{}";
1719 m_t << "}{\\fldrslt {\\cs37\\ul\\cf2 ";
1720 }
1721 else
1722 {
1723 m_t << "{\\b ";
1724 }
1726}
1727
1729{
1730 if (ref.isEmpty() && Config_getBool(RTF_HYPERLINKS))
1731 {
1732 m_t << "}}}";
1733 }
1734 else
1735 {
1736 m_t << "}";
1737 }
1739}
1740
1742{
1743 writeDotFile(df.file(), df.hasCaption(), df.srcFile(), df.srcLine());
1744}
1745void RTFDocVisitor::writeDotFile(const QCString &filename, bool hasCaption,
1746 const QCString &srcFile, int srcLine)
1747{
1748 QCString baseName=makeBaseName(filename);
1749 QCString outDir = Config_getString(RTF_OUTPUT);
1750 writeDotGraphFromFile(filename,outDir,baseName,GraphOutputFormat::BITMAP,srcFile,srcLine);
1751 QCString imgExt = getDotImageExtension();
1752 includePicturePreRTF(baseName + "." + imgExt, true, hasCaption);
1753}
1754
1756{
1757 writeMscFile(df.file(), df.hasCaption(), df.srcFile(), df.srcLine());
1758}
1759void RTFDocVisitor::writeMscFile(const QCString &fileName, bool hasCaption,
1760 const QCString &srcFile, int srcLine)
1761{
1762 QCString baseName=makeBaseName(fileName);
1763 QCString outDir = Config_getString(RTF_OUTPUT);
1764 writeMscGraphFromFile(fileName,outDir,baseName,MscOutputFormat::BITMAP,srcFile,srcLine);
1765 includePicturePreRTF(baseName + ".png", true, hasCaption);
1766}
1767
1769{
1770 QCString baseName=makeBaseName(df.file());
1771 QCString outDir = Config_getString(RTF_OUTPUT);
1772 writeDiaGraphFromFile(df.file(),outDir,baseName,DiaOutputFormat::BITMAP,df.srcFile(),df.srcLine());
1773 includePicturePreRTF(baseName + ".png", true, df.hasCaption());
1774}
1775
1776void RTFDocVisitor::writePlantUMLFile(const QCString &fileName, bool hasCaption)
1777{
1778 QCString baseName=makeBaseName(fileName);
1779 QCString outDir = Config_getString(RTF_OUTPUT);
1781 includePicturePreRTF(baseName + ".png", true, hasCaption);
1782}
void parseCodeFragment(OutputCodeList &codeOutList, const QCString &fileName, const QCString &blockId, const QCString &scopeName, bool showLineNumbers, bool trimLeft, bool stripCodeComments)
static CodeFragmentManager & instance()
virtual void parseCode(OutputCodeList &codeOutList, const QCString &scopeName, const QCString &input, SrcLangExt lang, bool stripCodeComments, bool isExampleBlock, const QCString &exampleName=QCString(), const FileDef *fileDef=nullptr, int startLine=-1, int endLine=-1, bool inlineFragment=FALSE, const MemberDef *memberDef=nullptr, bool showLineNumbers=TRUE, const Definition *searchCtx=nullptr, bool collectXRefs=TRUE)=0
Parses a source file or fragment with the goal to produce highlighted and cross-referenced output.
Class representing a directory in the file system.
Definition dir.h:75
bool remove(const std::string &path, bool acceptsAbsPath=true) const
Definition dir.cpp:314
Node representing an anchor.
Definition docnode.h:228
QCString anchor() const
Definition docnode.h:231
QCString file() const
Definition docnode.h:232
Node representing an auto List.
Definition docnode.h:566
bool isCheckedList() const
Definition docnode.h:577
bool isEnumList() const
Definition docnode.h:575
Node representing an item of a auto list.
Definition docnode.h:590
int itemNumber() const
Definition docnode.h:593
Node representing a citation of some bibliographic reference.
Definition docnode.h:244
QCString text() const
Definition docnode.h:251
QCString anchor() const
Definition docnode.h:250
QCString ref() const
Definition docnode.h:249
QCString file() const
Definition docnode.h:247
Node representing a dia file.
Definition docnode.h:725
QCString srcFile() const
Definition docnode.h:685
QCString file() const
Definition docnode.h:679
int srcLine() const
Definition docnode.h:686
bool hasCaption() const
Definition docnode.h:681
Node representing a dot file.
Definition docnode.h:707
Node representing an emoji.
Definition docnode.h:336
int index() const
Definition docnode.h:340
QCString name() const
Definition docnode.h:339
Node representing an item of a cross-referenced list.
Definition docnode.h:524
QCString name() const
Definition docnode.h:527
bool isInline() const
Definition docnode.h:531
QCString relPath() const
Definition docnode.h:529
Node representing a Hypertext reference.
Definition docnode.h:817
QCString url() const
Definition docnode.h:824
QCString file() const
Definition docnode.h:825
Node representing a horizontal ruler.
Definition docnode.h:215
Node representing an HTML blockquote.
Definition docnode.h:1285
Node representing a HTML table caption.
Definition docnode.h:1222
QCString anchor() const
Definition docnode.h:1229
QCString file() const
Definition docnode.h:1228
Node representing a HTML table cell.
Definition docnode.h:1187
const HtmlAttribList & attribs() const
Definition docnode.h:1199
Node representing a HTML description data.
Definition docnode.h:1175
Node representing a Html description list.
Definition docnode.h:895
Node representing a Html description item.
Definition docnode.h:882
Node Html details.
Definition docnode.h:851
const DocNodeVariant * summary() const
Definition docnode.h:858
Node Html heading.
Definition docnode.h:867
int level() const
Definition docnode.h:871
Node representing a Html list.
Definition docnode.h:994
const HtmlAttribList & attribs() const
Definition docnode.h:1000
Type type() const
Definition docnode.h:999
Node representing a HTML list item.
Definition docnode.h:1159
const HtmlAttribList & attribs() const
Definition docnode.h:1164
Node representing a HTML table row.
Definition docnode.h:1240
bool isHeading() const
Definition docnode.cpp:1883
size_t numCells() const
Definition docnode.h:1245
Node Html summary.
Definition docnode.h:838
Node representing a HTML table.
Definition docnode.h:1263
const DocNodeVariant * caption() const
Definition docnode.cpp:2029
Node representing an image.
Definition docnode.h:636
QCString name() const
Definition docnode.h:642
Type type() const
Definition docnode.h:641
bool isInlineImage() const
Definition docnode.h:648
bool hasCaption() const
Definition docnode.h:643
Node representing a include/dontinclude operator block.
Definition docnode.h:472
bool stripCodeComments() const
Definition docnode.h:501
bool isLast() const
Definition docnode.h:498
QCString includeFileName() const
Definition docnode.h:504
QCString text() const
Definition docnode.h:494
QCString context() const
Definition docnode.h:496
QCString exampleFile() const
Definition docnode.h:503
int line() const
Definition docnode.h:492
Type type() const
Definition docnode.h:480
bool isFirst() const
Definition docnode.h:497
bool showLineNo() const
Definition docnode.h:493
bool isExample() const
Definition docnode.h:502
Node representing an included text block from file.
Definition docnode.h:430
QCString blockId() const
Definition docnode.h:449
QCString extension() const
Definition docnode.h:445
bool stripCodeComments() const
Definition docnode.h:450
@ LatexInclude
Definition docnode.h:432
@ SnippetWithLines
Definition docnode.h:433
@ DontIncWithLines
Definition docnode.h:434
@ IncWithLines
Definition docnode.h:433
@ HtmlInclude
Definition docnode.h:432
@ VerbInclude
Definition docnode.h:432
@ DontInclude
Definition docnode.h:432
@ DocbookInclude
Definition docnode.h:434
Type type() const
Definition docnode.h:446
QCString exampleFile() const
Definition docnode.h:452
QCString text() const
Definition docnode.h:447
QCString file() const
Definition docnode.h:444
bool trimLeft() const
Definition docnode.h:454
bool isExample() const
Definition docnode.h:451
QCString context() const
Definition docnode.h:448
Node representing an entry in the index.
Definition docnode.h:547
QCString entry() const
Definition docnode.h:554
Node representing an internal section of documentation.
Definition docnode.h:963
Node representing an internal reference to some item.
Definition docnode.h:801
QCString file() const
Definition docnode.h:805
QCString anchor() const
Definition docnode.h:807
Node representing a line break.
Definition docnode.h:201
Node representing a word that can be linked to something.
Definition docnode.h:164
QCString file() const
Definition docnode.h:170
QCString ref() const
Definition docnode.h:172
QCString word() const
Definition docnode.h:169
QCString anchor() const
Definition docnode.h:173
Node representing a msc file.
Definition docnode.h:716
DocNodeVariant * parent()
Definition docnode.h:89
Node representing an block of paragraphs.
Definition docnode.h:973
Node representing a paragraph in the documentation tree.
Definition docnode.h:1074
bool isLast() const
Definition docnode.h:1082
Node representing a parameter list.
Definition docnode.h:1119
const DocNodeList & parameters() const
Definition docnode.h:1123
const DocNodeList & paramTypes() const
Definition docnode.h:1124
DocParamSect::Direction direction() const
Definition docnode.h:1127
const DocNodeList & paragraphs() const
Definition docnode.h:1125
Node representing a parameter section.
Definition docnode.h:1047
bool hasInOutSpecifier() const
Definition docnode.h:1063
bool hasTypeSpecifier() const
Definition docnode.h:1064
Type type() const
Definition docnode.h:1062
Node representing a uml file.
Definition docnode.h:734
Node representing a reference to some item.
Definition docnode.h:772
QCString anchor() const
Definition docnode.h:779
QCString targetTitle() const
Definition docnode.h:780
bool isSubPage() const
Definition docnode.h:786
QCString file() const
Definition docnode.h:776
QCString ref() const
Definition docnode.h:778
bool hasLinkText() const
Definition docnode.h:782
Root node of documentation tree.
Definition docnode.h:1307
bool singleLine() const
Definition docnode.h:1313
bool indent() const
Definition docnode.h:1312
Node representing a reference to a section.
Definition docnode.h:929
Node representing a list of section references.
Definition docnode.h:953
Node representing a normal section.
Definition docnode.h:908
QCString file() const
Definition docnode.h:916
int level() const
Definition docnode.h:912
QCString anchor() const
Definition docnode.h:914
const DocNodeVariant * title() const
Definition docnode.h:913
Node representing a separator.
Definition docnode.h:360
QCString chars() const
Definition docnode.h:364
Node representing a simple list.
Definition docnode.h:984
Node representing a simple list item.
Definition docnode.h:1147
const DocNodeVariant * paragraph() const
Definition docnode.h:1151
Node representing a simple section.
Definition docnode.h:1011
Type type() const
Definition docnode.h:1020
const DocNodeVariant * title() const
Definition docnode.h:1027
Node representing a separator between two simple sections of the same type.
Definition docnode.h:1038
Node representing a style change.
Definition docnode.h:264
Style style() const
Definition docnode.h:302
bool enable() const
Definition docnode.h:304
Node representing a special symbol.
Definition docnode.h:323
HtmlEntityMapper::SymType symbol() const
Definition docnode.h:327
Root node of a text fragment.
Definition docnode.h:1298
Node representing a simple section title.
Definition docnode.h:603
Node representing a URL (or email address)
Definition docnode.h:187
QCString url() const
Definition docnode.h:191
bool isEmail() const
Definition docnode.h:192
Node representing a verbatim, unparsed text fragment.
Definition docnode.h:371
QCString srcFile() const
Definition docnode.h:392
int srcLine() const
Definition docnode.h:393
bool hasCaption() const
Definition docnode.h:385
QCString language() const
Definition docnode.h:383
bool isExample() const
Definition docnode.h:380
QCString context() const
Definition docnode.h:379
Type type() const
Definition docnode.h:377
QCString text() const
Definition docnode.h:378
QCString exampleFile() const
Definition docnode.h:381
QCString engine() const
Definition docnode.h:388
@ JavaDocLiteral
Definition docnode.h:373
Node representing a VHDL flow chart.
Definition docnode.h:743
CodeParserInterface & getCodeParser(const QCString &langExt)
void pushHidden(bool hide)
bool popHidden()
Node representing some amount of white space.
Definition docnode.h:349
QCString chars() const
Definition docnode.h:353
Node representing a word.
Definition docnode.h:152
QCString word() const
Definition docnode.h:155
Node representing an item of a cross-referenced list.
Definition docnode.h:615
QCString anchor() const
Definition docnode.h:619
QCString file() const
Definition docnode.h:618
QCString title() const
Definition docnode.h:620
const char * unicode(int index) const
Access routine to the unicode sequence for the Emoji entity.
Definition emoji.cpp:2016
static EmojiEntityMapper & instance()
Returns the one and only instance of the Emoji entity mapper.
Definition emoji.cpp:1978
Minimal replacement for QFileInfo.
Definition fileinfo.h:23
std::string fileName() const
Definition fileinfo.cpp:118
std::string dirPath(bool absPath=true) const
Definition fileinfo.cpp:137
static HtmlEntityMapper & instance()
Returns the one and only instance of the HTML entity mapper.
const char * rtf(SymType symb) const
Access routine to the RTF code of the HTML entity.
Class representing a list of different code generators.
Definition outputlist.h:164
QCString writePlantUMLSource(const QCString &outDirArg, const QCString &fileName, const QCString &content, OutputFormat format, const QCString &engine, const QCString &srcFile, int srcLine, bool inlineCode)
Write a PlantUML compatible file.
Definition plantuml.cpp:27
static PlantumlManager & instance()
Definition plantuml.cpp:156
void generatePlantUMLOutput(const QCString &baseName, const QCString &outDir, OutputFormat format)
Convert a PlantUML file to an image.
Definition plantuml.cpp:127
This is an alternative implementation of QCString.
Definition qcstring.h:101
size_t length() const
Returns the length of the string, not counting the 0-terminator.
Definition qcstring.h:153
bool startsWith(const char *s) const
Definition qcstring.h:492
QCString mid(size_t index, size_t len=static_cast< size_t >(-1)) const
Definition qcstring.h:226
bool isEmpty() const
Returns TRUE iff the string is empty.
Definition qcstring.h:150
const std::string & str() const
Definition qcstring.h:537
QCString & setNum(short n)
Definition qcstring.h:444
QCString right(size_t len) const
Definition qcstring.h:219
QCString & sprintf(const char *format,...)
Definition qcstring.cpp:29
@ ExplicitSize
Definition qcstring.h:133
int findRev(char c, int index=-1, bool cs=TRUE) const
Definition qcstring.cpp:91
const char * data() const
Returns a pointer to the contents of the string in the form of a 0-terminated C string.
Definition qcstring.h:159
void startLink(const QCString &ref, const QCString &file, const QCString &anchor)
void filter(const QCString &str, bool verbatim=FALSE)
int indentLevel() const
void visitChildren(const T &t)
void writeDotFile(const QCString &fileName, bool hasCaption, const QCString &srcFile, int srcLine)
void includePicturePreRTF(const QCString &name, bool isTypeRTF, bool hasCaption, bool inlineImage=FALSE)
QCString m_langExt
void writeDiaFile(const DocDiaFile &)
void includePicturePostRTF(bool isTypeRTF, bool hasCaption, bool inlineImage=FALSE)
OutputCodeList & m_ci
RTFDocVisitor(TextStream &t, OutputCodeList &ci, const QCString &langExt, int hierarchyLevel=0)
QCString getStyle(const QCString &name)
void writePlantUMLFile(const QCString &fileName, bool hasCaption)
static const int maxIndentLevels
void writeMscFile(const QCString &fileName, bool hasCaption, const QCString &srcFile, int srcLine)
TextStream & m_t
QCString getListTable(const int id)
void endLink(const QCString &ref)
RTFListItemInfo m_listItemInfo[maxIndentLevels]
void operator()(const DocWord &)
static constexpr int MaxLevel
Definition section.h:39
static constexpr int MinLevel
Definition section.h:32
Text streaming class that buffers data.
Definition textstream.h:36
#define Config_getBool(name)
Definition config.h:33
#define Config_getString(name)
Definition config.h:32
void writeDiaGraphFromFile(const QCString &inFile, const QCString &outDir, const QCString &outFile, DiaOutputFormat format, const QCString &srcFile, int srcLine)
Definition dia.cpp:26
static QCString makeBaseName(const QCString &name)
void writeDotGraphFromFile(const QCString &inFile, const QCString &outDir, const QCString &outFile, GraphOutputFormat format, const QCString &srcFile, int srcLine)
Definition dot.cpp:230
std::unique_ptr< FileDef > createFileDef(const QCString &p, const QCString &n, const QCString &ref, const QCString &dn)
Definition filedef.cpp:267
Translator * theTranslator
Definition language.cpp:71
#define err(fmt,...)
Definition message.h:84
void writeMscGraphFromFile(const QCString &inFile, const QCString &outDir, const QCString &outFile, MscOutputFormat format, const QCString &srcFile, int srcLine)
Definition msc.cpp:156
std::ofstream openOutputStream(const QCString &name, bool append=false)
Definition portable.cpp:665
Portable versions of functions that are platform dependent.
const char * qPrint(const char *s)
Definition qcstring.h:672
#define TRUE
Definition qcstring.h:37
#define FALSE
Definition qcstring.h:34
#define ASSERT(x)
Definition qcstring.h:39
static QCString align(const DocHtmlCell &cell)
static QCString makeBaseName(const QCString &name)
#define DBG_RTF(x)
QCString rtfFormatBmkStr(const QCString &name)
Definition rtfgen.cpp:2869
StyleDataMap rtf_Style
Definition rtfstyle.cpp:362
char rtf_Style_Reset[]
Definition rtfstyle.cpp:49
Rtf_Table_Default rtf_Table_Default[]
Definition rtfstyle.cpp:245
const int rtf_pageWidth
Definition rtfstyle.h:26
const char * reference() const
Definition rtfstyle.h:69
SrcLangExt
Language as given by extension.
Definition types.h:42
SrcLangExt getLanguageFromFileName(const QCString &fileName, SrcLangExt defLang)
Definition util.cpp:5549
QCString integerToRoman(int n, bool upper)
Definition util.cpp:7026
QCString stripPath(const QCString &s)
Definition util.cpp:5292
bool readInputFile(const QCString &fileName, std::string &contents, bool filter, bool isSourceCode)
read a file name fileName and optionally filter and transcode it
Definition util.cpp:5841
SrcLangExt getLanguageFromCodeLang(QCString &fileName)
Routine to handle the language attribute of the \code command.
Definition util.cpp:5567
QCString integerToAlpha(int n, bool upper)
Definition util.cpp:7010
QCString getDotImageExtension()
Definition util.cpp:6617
bool copyFile(const QCString &src, const QCString &dest)
Copies the contents of file with name src to the newly created file with name dest.
Definition util.cpp:6170
QCString getFileNameExtension(const QCString &fn)
Definition util.cpp:5591
A bunch of utility functions.