1 /******************************************************************************
5 * Copyright (C) 1997-2015 by Parker Waechter & Dimitri van Heesch.
7 * Style sheet additions by Alexander Bartolich
9 * Permission to use, copy, modify, and distribute this software and its
10 * documentation under the terms of the GNU General Public License is hereby
11 * granted. No representations are made about the suitability of this software
12 * for any purpose. It is provided "as is" without express or implied warranty.
13 * See the GNU General Public License for more details.
15 * Documents produced by Doxygen are derivative works derived from the
16 * input used in their production; they are not affected by this license.
24 #include <qtextstream.h>
37 #include "rtfdocvisitor.h"
38 #include "docparser.h"
40 #include "vhdldocgen.h"
43 #include "classlist.h"
45 #include "namespacedef.h"
47 //#define DBG_RTF(x) x;
50 static QCString dateToRTFDateString()
52 const QDateTime &d = QDateTime::currentDateTime();
54 result.sprintf("\\yr%d\\mo%d\\dy%d\\hr%d\\min%d\\sec%d",
55 d.date().year(), d.date().month(), d.date().day(),
56 d.time().hour(),d.time().minute(),d.time().second());
60 RTFGenerator::RTFGenerator() : OutputGenerator()
62 dir=Config_getString(RTF_OUTPUT);
64 //insideTabbing=FALSE;
66 m_bstartedBody = FALSE;
67 m_omitParagraph = FALSE;
69 m_prettyCode=Config_getBool(RTF_SOURCE_CODE);
72 RTFGenerator::~RTFGenerator()
76 //void RTFGenerator::append(const OutputGenerator *g)
78 // t << g->getContents();
79 // col+=((RTFGenerator *)g)->col;
80 // //insideTabbing=insideTabbing || ((RTFGenerator *)g)->insideTabbing;
81 // m_listLevel=((RTFGenerator *)g)->m_listLevel;
82 // m_omitParagraph=((RTFGenerator *)g)->m_omitParagraph;
83 // //printf("RTFGenerator::append(%s) insideTabbing=%s\n", g->getContents().data(),
84 // // insideTabbing ? "TRUE" : "FALSE" );
87 //OutputGenerator *RTFGenerator::copy()
89 // RTFGenerator *result = new RTFGenerator;
90 // //result->insideTabbing=insideTabbing;
91 // result->m_listLevel=m_listLevel;
92 // result->m_omitParagraph=m_omitParagraph;
96 void RTFGenerator::writeStyleSheetFile(QFile &file)
99 t << "# Generated by doxygen " << versionString << "\n\n";
100 t << "# This file describes styles used for generating RTF output.\n";
101 t << "# All text after a hash (#) is considered a comment and will be ignored.\n";
102 t << "# Remove a hash to activate a line.\n\n";
105 for ( i=0 ; rtf_Style_Default[i].reference!=0 ; i++ )
107 t << "# " << rtf_Style_Default[i].name << " = "
108 << rtf_Style_Default[i].reference
109 << rtf_Style_Default[i].definition << endl;
113 void RTFGenerator::writeExtensionsFile(QFile &file)
115 FTextStream t(&file);
116 t << "# Generated by doxygen " << versionString << "\n\n";
117 t << "# This file describes extensions used for generating RTF output.\n";
118 t << "# All text after a hash (#) is considered a comment and will be ignored.\n";
119 t << "# Remove a hash to activate a line.\n\n";
121 t << "# Overrides the project title.\n";
123 t << "#Title = \n\n";
125 t << "# Name of the company that produced this document.\n";
126 t << "#Company = \n\n";
128 t << "# Filename of a company or project logo.\n";
129 t << "#LogoFilename = \n\n";
131 t << "# Author of the document.\n";
132 t << "#Author = \n\n";
134 t << "# Type of document (e.g. Design Specification, User Manual, etc.).\n";
135 t << "#DocumentType = \n\n";
137 t << "# Document tracking number.\n";
138 t << "#DocumentId = \n\n";
140 t << "# Name of the author's manager.\n";
141 t << "# This field is not displayed in the document itself, but it is \n";
142 t << "# available in the information block of the rtf file. In Microsoft \n";
143 t << "# Word, it is available under File:Properties.\n";
144 t << "#Manager = \n\n";
146 t << "# Subject of the document.\n";
147 t << "# This field is not displayed in the document itself, but it is \n";
148 t << "# available in the information block of the rtf file. In Microsoft \n";
149 t << "# Word, it is available under File:Properties.\n";
150 t << "#Subject = \n\n";
152 t << "# Comments regarding the document.\n";
153 t << "# This field is not displayed in the document itself, but it is \n";
154 t << "# available in the information block of the rtf file. In Microsoft \n";
155 t << "# Word, it is available under File:Properties.\n";
156 t << "#Comments = \n\n";
158 t << "# Keywords associated with the document.\n";
159 t << "# This field is not displayed in the document itself, but it is \n";
160 t << "# available in the information block of the rtf file. In Microsoft \n";
161 t << "# Word, it is available under File:Properties.\n";
162 t << "#Keywords = \n\n";
166 void RTFGenerator::init()
168 QCString dir=Config_getString(RTF_OUTPUT);
170 if (!d.exists() && !d.mkdir(dir))
172 err("Could not create output directory %s\n",dir.data());
175 rtf_Style.setAutoDelete(TRUE);
177 // first duplicate strings of rtf_Style_Default
178 const struct Rtf_Style_Default* def = rtf_Style_Default;
179 while(def->reference != 0)
181 if (def->definition == 0)
182 err("Internal: rtf_Style_Default[%s] has no definition.\n", def->name);
183 StyleData* styleData = new StyleData(def->reference, def->definition);
184 rtf_Style.insert(def->name, styleData);
188 // overwrite some (or all) definitions from file
189 QCString &rtfStyleSheetFile = Config_getString(RTF_STYLESHEET_FILE);
190 if (!rtfStyleSheetFile.isEmpty())
192 loadStylesheet(rtfStyleSheetFile, rtf_Style);
195 // If user has defined an extension file, load its contents.
196 QCString &rtfExtensionsFile = Config_getString(RTF_EXTENSIONS_FILE);
197 if (!rtfExtensionsFile.isEmpty())
199 loadExtensions(rtfExtensionsFile);
205 static QCString makeIndexName(const char *s,int i)
208 result+=(char)(i+'0');
212 void RTFGenerator::beginRTFDocument()
214 /* all the included RTF files should begin with the
217 t <<"{\\rtf1\\ansi\\ansicpg" << theTranslator->trRTFansicp();
218 t <<"\\uc1 \\deff0\\deflang1033\\deflangfe1033\n";
220 DBG_RTF(t <<"{\\comment Beginning font list}\n")
222 t <<"{\\f0\\froman\\fcharset" << theTranslator->trRTFCharSet();
223 t <<"\\fprq2{\\*\\panose 02020603050405020304}Times New Roman;}\n";
224 t <<"{\\f1\\fswiss\\fcharset" << theTranslator->trRTFCharSet();
225 t <<"\\fprq2{\\*\\panose 020b0604020202020204}Arial;}\n";
226 t <<"{\\f2\\fmodern\\fcharset" << theTranslator->trRTFCharSet();
227 t <<"\\fprq1{\\*\\panose 02070309020205020404}Courier New;}\n";
228 t <<"{\\f3\\froman\\fcharset2\\fprq2{\\*\\panose 05050102010706020507}Symbol;}\n";
230 DBG_RTF(t <<"{\\comment begin colors}\n")
232 t <<"\\red0\\green0\\blue0;";
233 t <<"\\red0\\green0\\blue255;";
234 t <<"\\red0\\green255\\blue255;";
235 t <<"\\red0\\green255\\blue0;";
236 t <<"\\red255\\green0\\blue255;";
237 t <<"\\red255\\green0\\blue0;";
238 t <<"\\red255\\green255\\blue0;";
239 t <<"\\red255\\green255\\blue255;";
240 t <<"\\red0\\green0\\blue128;";
241 t <<"\\red0\\green128\\blue128;";
242 t <<"\\red0\\green128\\blue0;";
243 t <<"\\red128\\green0\\blue128;";
244 t <<"\\red128\\green0\\blue0;";
245 t <<"\\red128\\green128\\blue0;";
246 t <<"\\red128\\green128\\blue128;";
247 t <<"\\red192\\green192\\blue192;";
249 // code highlighting colors. Note order is important see also RTFGenerator::startFontClass
250 t <<"\\red0\\green128\\blue0;"; // keyword = index 17
251 t <<"\\red96\\green64\\blue32;"; // keywordtype
252 t <<"\\rede0\\green128\\blue0;"; // keywordflow
253 t <<"\\red128\\green0\\blue0;"; // comment
254 t <<"\\red128\\green96\\blue32;"; // preprocessor
255 t <<"\\red0\\green32\\blue128;"; // stringliteral
256 t <<"\\red0\\green128\\blue128;"; // charliteral
257 t <<"\\red255\\green0\\blue255;"; // vhdldigit
258 t <<"\\red0\\green0\\blue0;"; // vhdlchar
259 t <<"\\red112\\green0\\blue112;"; // vhdlkeyword
260 t <<"\\red255\\green0\\blue0;"; // vhdllogic
264 DBG_RTF(t <<"{\\comment Beginning style list}\n")
265 t <<"{\\stylesheet\n";
266 t <<"{\\widctlpar\\adjustright \\fs20\\cgrid \\snext0 Normal;}\n";
268 // set the paper dimensions according to PAPER_TYPE
269 QCString paperName = Config_getEnum(PAPER_TYPE);
273 t << "\\paperw11900\\paperh16840"; // width & height values are inches * 1440
275 else if (paperName=="letter")
277 t << "\\paperw12240\\paperh15840";
279 else if (paperName=="legal")
281 t << "\\paperw12240\\paperh20160";
283 else if (paperName=="executive")
285 t << "\\paperw10440\\paperh15120";
287 t << "\\margl1800\\margr1800\\margt1440\\margb1440\\gutter0\\ltrsect}\n";
289 // sort styles ascending by \s-number via an intermediate QArray
290 QDictIterator<StyleData> iter(rtf_Style);
291 const StyleData* style;
292 unsigned maxIndex = 0;
293 for(; (style = iter.current()); ++iter)
295 unsigned index = style->index;
296 if (maxIndex < index) maxIndex = index;
298 QArray<const StyleData*> array(maxIndex + 1);
300 ASSERT(maxIndex < array.size());
303 for(; (style = iter.current()); ++iter)
305 unsigned index = style->index;
306 if (array.at(index) != 0)
308 QCString key(iter.currentKey());
309 msg("Style '%s' redefines \\s%d.\n", key.data(), index);
311 array.at(index) = style;
314 // write array elements
315 unsigned size = array.size();
316 for(unsigned i = 0; i < size; i++)
318 const StyleData* style = array.at(i);
320 t <<"{" << style->reference << style->definition << ";}\n";
324 // this comment is needed for postprocessing!
325 t <<"{\\comment begin body}" << endl;
329 void RTFGenerator::beginRTFChapter()
332 DBG_RTF(t << "{\\comment BeginRTFChapter}\n")
333 t << rtf_Style_Reset;
335 // if we are compact, no extra page breaks...
336 if (Config_getBool(COMPACT_RTF))
338 // t <<"\\sect\\sectd\\sbknone\n";
339 t <<"\\sect\\sbknone\n";
340 rtfwriteRuler_thick();
343 t <<"\\sect\\sbkpage\n";
344 //t <<"\\sect\\sectd\\sbkpage\n";
346 t << rtf_Style["Heading1"]->reference << "\n";
349 void RTFGenerator::beginRTFSection()
352 DBG_RTF(t << "{\\comment BeginRTFSection}\n")
353 t << rtf_Style_Reset;
355 // if we are compact, no extra page breaks...
356 if (Config_getBool(COMPACT_RTF))
358 // t <<"\\sect\\sectd\\sbknone\n";
359 t <<"\\sect\\sbknone\n";
360 rtfwriteRuler_emboss();
363 t <<"\\sect\\sbkpage\n";
364 //t <<"\\sect\\sectd\\sbkpage\n";
366 t << rtf_Style["Heading2"]->reference << "\n";
369 void RTFGenerator::startFile(const char *name,const char *,const char *)
371 //setEncoding(QCString().sprintf("CP%s",theTranslator->trRTFansicp()));
372 QCString fileName=name;
373 relPath = relativePathToRoot(fileName);
375 if (fileName.right(4)!=".rtf" ) fileName+=".rtf";
376 startPlainFile(fileName);
380 void RTFGenerator::endFile()
382 DBG_RTF(t << "{\\comment endFile}\n")
388 void RTFGenerator::startProjectNumber()
390 DBG_RTF(t <<"{\\comment startProjectNumber }" << endl)
394 void RTFGenerator::endProjectNumber()
396 DBG_RTF(t <<"{\\comment endProjectNumber }" << endl)
399 void RTFGenerator::startIndexSection(IndexSections is)
401 //QCString paperName;
407 case isTitlePageStart:
409 // get readyfor author etc
412 t << "{\\title {\\comment ";
414 case isTitlePageAuthor:
416 if (rtf_subject) t << "{\\subject " << rtf_subject << "}\n";
417 if (rtf_comments) t << "{\\comment " << rtf_comments << "}\n";
418 if (rtf_company) t << "{\\company " << rtf_company << "}\n";
419 if (rtf_author) t << "{\\author " << rtf_author << "}\n";
420 if (rtf_manager) t << "{\\manager " << rtf_manager << "}\n";
421 if (rtf_documentType) t << "{\\category " << rtf_documentType << "}\n";
422 if (rtf_keywords) t << "{\\keywords " << rtf_keywords << "}\n";
429 //case isPackageIndex:
431 // beginRTFChapter();
441 case isNamespaceIndex:
445 case isClassHierarchyIndex:
447 DBG_RTF(t << "{\\comment start classhierarchy}\n")
450 case isCompoundIndex:
451 //Annotated Compound Index
455 //Annotated File Index
462 case isModuleDocumentation:
464 //Module Documentation
465 GroupSDict::Iterator gli(*Doxygen::groupSDict);
468 for (gli.toFirst();(gd=gli.current()) && !found;++gli)
470 if (!gd->isReference())
478 case isDirDocumentation:
480 //Directory Documentation
481 SDict<DirDef>::Iterator dli(*Doxygen::directories);
484 for (dli.toFirst();(dd=dli.current()) && !found;++dli)
486 if (dd->isLinkableInProject())
494 case isNamespaceDocumentation:
496 // Namespace Documentation
497 NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
500 for (nli.toFirst();(nd=nli.current()) && !found;++nli)
502 if (nd->isLinkableInProject())
510 case isClassDocumentation:
512 //Compound Documentation
513 ClassSDict::Iterator cli(*Doxygen::classSDict);
516 for (cli.toFirst();(cd=cli.current()) && !found;++cli)
518 if (cd->isLinkableInProject() &&
519 cd->templateMaster()==0 &&
520 !cd->isEmbeddedInOuterScope()
529 case isFileDocumentation:
533 FileNameListIterator fnli(*Doxygen::inputNameList);
535 for (fnli.toFirst();(fn=fnli.current());++fnli)
537 FileNameIterator fni(*fn);
539 for (;(fd=fni.current());++fni)
541 if (fd->isLinkableInProject())
554 case isExampleDocumentation:
556 //Example Documentation
560 case isPageDocumentation:
566 case isPageDocumentation2:
576 void RTFGenerator::endIndexSection(IndexSections is)
578 bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN);
579 bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL);
580 static bool sourceBrowser = Config_getBool(SOURCE_BROWSER);
581 static QCString projectName = Config_getString(PROJECT_NAME);
585 case isTitlePageStart:
587 // User has overridden document title in extensions file
588 t << "}" << rtf_title;
590 t << "}" << projectName;
592 case isTitlePageAuthor:
595 t << "{\\creatim " << dateToRTFDateString() << "}\n}";
596 DBG_RTF(t << "{\\comment end of infoblock}\n");
597 // setup for this section
598 t << rtf_Style_Reset <<"\n";
599 t <<"\\sectd\\pgnlcrm\n";
600 t <<"{\\footer "<<rtf_Style["Footer"]->reference << "{\\chpgn}}\n";
602 DBG_RTF(t << "{\\comment begin title page}\n")
605 t << rtf_Style_Reset << rtf_Style["SubTitle"]->reference << endl; // set to title style
607 t << "\\vertalc\\qc\\par\\par\\par\\par\\par\\par\\par\n";
608 if (rtf_logoFilename)
610 t << "{\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"" << rtf_logoFilename;
611 t << "\" \\\\d \\\\*MERGEFORMAT} {\\fldrslt IMAGE }}\\par\\par\n";
615 t << rtf_company << "\\par\\par\n";
618 t << rtf_Style_Reset << rtf_Style["Title"]->reference << endl; // set to title style
620 // User has overridden document title in extensions file
621 t << "{\\field\\fldedit {\\*\\fldinst TITLE \\\\*MERGEFORMAT}{\\fldrslt " << rtf_title << "}}\\par" << endl;
624 DocText *root = validatingParseText(projectName);
625 t << "{\\field\\fldedit {\\*\\fldinst TITLE \\\\*MERGEFORMAT}{\\fldrslt ";
627 t << "}}\\par" << endl;
631 t << rtf_Style_Reset << rtf_Style["SubTitle"]->reference << endl; // set to title style
633 if (rtf_documentType)
635 t << rtf_documentType << "\\par\n";
639 t << rtf_documentId << "\\par\n";
641 t << "\\par\\par\\par\\par\\par\\par\\par\\par\\par\\par\\par\\par\n";
643 t << rtf_Style_Reset << rtf_Style["SubTitle"]->reference << endl; // set to subtitle style
645 t << "{\\field\\fldedit {\\*\\fldinst AUTHOR \\\\*MERGEFORMAT}{\\fldrslt "<< rtf_author << " }}\\par" << endl;
647 t << "{\\field\\fldedit {\\*\\fldinst AUTHOR \\\\*MERGEFORMAT}{\\fldrslt AUTHOR}}\\par" << endl;
649 t << theTranslator->trVersion() << " " << Config_getString(PROJECT_NUMBER) << "\\par";
650 t << "{\\field\\fldedit {\\*\\fldinst CREATEDATE \\\\*MERGEFORMAT}"
651 "{\\fldrslt "<< dateToString(FALSE) << " }}\\par"<<endl;
653 DBG_RTF(t << "{\\comment End title page}" << endl)
655 // table of contents section
656 DBG_RTF(t << "{\\comment Table of contents}\n")
658 t << rtf_Style_Reset << endl;
659 t << rtf_Style["Heading1"]->reference;
660 t << theTranslator->trRTFTableOfContents() << "\\par"<< endl;
661 t << rtf_Style_Reset << "\\par" << endl;
662 t << "{\\field\\fldedit {\\*\\fldinst TOC \\\\f \\\\*MERGEFORMAT}{\\fldrslt Table of contents}}\\par\n";
663 t << rtf_Style_Reset << endl;
667 t << "\\par " << rtf_Style_Reset << endl;
668 if (!Doxygen::mainPage || Doxygen::mainPage->title().isEmpty())
670 t << "{\\tc \\v " << theTranslator->trMainPage() << "}"<< endl;
674 t << "{\\tc \\v " << substitute(Doxygen::mainPage->title(),"%","") << "}"<< endl;
676 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
677 //if (Config_getBool(GENERATE_TREEVIEW)) t << "main"; else t << "index";
679 t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
681 //case isPackageIndex:
682 // t << "\\par " << rtf_Style_Reset << endl;
683 // t << "{\\tc \\v " << theTranslator->trPackageList() << "}"<< endl;
684 // t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"packages.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
687 t << "\\par " << rtf_Style_Reset << endl;
688 t << "{\\tc \\v " << theTranslator->trModuleIndex() << "}"<< endl;
689 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"modules.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
692 t << "\\par " << rtf_Style_Reset << endl;
693 t << "{\\tc \\v " << theTranslator->trDirIndex() << "}"<< endl;
694 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"dirs.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
696 case isNamespaceIndex:
697 t << "\\par " << rtf_Style_Reset << endl;
700 t << "{\\tc \\v " << theTranslator->trModulesIndex() << "}" << endl;
704 t << "{\\tc \\v " << theTranslator->trNamespaceIndex() << "}" << endl;
707 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"namespaces.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
709 case isClassHierarchyIndex:
710 t << "\\par " << rtf_Style_Reset << endl;
711 t << "{\\tc \\v " << theTranslator->trHierarchicalIndex() << "}"<< endl;
712 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"hierarchy.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
714 case isCompoundIndex:
715 t << "\\par " << rtf_Style_Reset << endl;
718 t << "{\\tc \\v " << theTranslator->trCompoundIndexFortran() << "}"<< endl;
722 t << "{\\tc \\v " << theTranslator->trDesignUnitIndex() << "}"<< endl;
726 t << "{\\tc \\v " << theTranslator->trCompoundIndex() << "}"<< endl;
728 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"annotated.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
731 t << "\\par " << rtf_Style_Reset << endl;
732 t << "{\\tc \\v " << theTranslator->trFileIndex() << "}"<< endl;
733 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"files.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
736 t << "\\par " << rtf_Style_Reset << endl;
737 t << "{\\tc \\v " << theTranslator->trPageIndex() << "}"<< endl;
738 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"pages.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
740 case isModuleDocumentation:
742 GroupSDict::Iterator gli(*Doxygen::groupSDict);
744 t << "{\\tc \\v " << theTranslator->trModuleDocumentation() << "}"<< endl;
745 for (gli.toFirst();(gd=gli.current());++gli)
747 if (!gd->isReference())
749 t << "\\par " << rtf_Style_Reset << endl;
750 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
751 t << gd->getOutputFileBase();
752 t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
757 case isDirDocumentation:
759 SDict<DirDef>::Iterator dli(*Doxygen::directories);
761 t << "{\\tc \\v " << theTranslator->trDirDocumentation() << "}"<< endl;
762 for (dli.toFirst();(dd=dli.current());++dli)
764 if (dd->isLinkableInProject())
766 t << "\\par " << rtf_Style_Reset << endl;
767 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
768 t << dd->getOutputFileBase();
769 t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
774 case isNamespaceDocumentation:
776 NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
779 for (nli.toFirst();(nd=nli.current()) && !found;++nli)
781 if (nd->isLinkableInProject())
783 t << "\\par " << rtf_Style_Reset << endl;
784 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
785 t << nd->getOutputFileBase();
786 t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
790 while ((nd=nli.current()))
792 if (nd->isLinkableInProject())
794 t << "\\par " << rtf_Style_Reset << endl;
796 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
797 t << nd->getOutputFileBase();
798 t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
804 case isClassDocumentation:
806 ClassSDict::Iterator cli(*Doxygen::classSDict);
811 t << "{\\tc \\v " << theTranslator->trTypeDocumentation() << "}"<< endl;
815 t << "{\\tc \\v " << theTranslator->trClassDocumentation() << "}"<< endl;
817 for (cli.toFirst();(cd=cli.current()) && !found;++cli)
819 if (cd->isLinkableInProject() &&
820 cd->templateMaster()==0 &&
821 !cd->isEmbeddedInOuterScope()
824 t << "\\par " << rtf_Style_Reset << endl;
825 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
826 t << cd->getOutputFileBase();
827 t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
831 for (;(cd=cli.current());++cli)
833 if (cd->isLinkableInProject() &&
834 cd->templateMaster()==0 &&
835 !cd->isEmbeddedInOuterScope()
838 t << "\\par " << rtf_Style_Reset << endl;
840 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
841 t << cd->getOutputFileBase();
842 t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
847 case isFileDocumentation:
851 t << "{\\tc \\v " << theTranslator->trFileDocumentation() << "}"<< endl;
852 FileNameListIterator fnli(*Doxygen::inputNameList);
854 for (fnli.toFirst();(fn=fnli.current());++fnli)
856 FileNameIterator fni(*fn);
858 for (;(fd=fni.current());++fni)
860 if (fd->isLinkableInProject())
864 t << "\\par " << rtf_Style_Reset << endl;
865 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
866 t << fd->getOutputFileBase();
867 t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
868 if (sourceBrowser && m_prettyCode && fd->generateSourceFile())
870 t << "\\par " << rtf_Style_Reset << endl;
871 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"" << fd->getSourceFileBase() << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
877 t << "\\par " << rtf_Style_Reset << endl;
879 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
880 t << fd->getOutputFileBase();
881 t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
882 if (sourceBrowser && m_prettyCode && fd->generateSourceFile())
884 t << "\\par " << rtf_Style_Reset << endl;
885 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"" << fd->getSourceFileBase() << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
893 case isExampleDocumentation:
896 t << "{\\tc \\v " << theTranslator->trExampleDocumentation() << "}"<< endl;
897 PageSDict::Iterator pdi(*Doxygen::exampleSDict);
898 PageDef *pd=pdi.toFirst();
901 t << "\\par " << rtf_Style_Reset << endl;
902 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
903 t << pd->getOutputFileBase();
904 t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
906 for (++pdi;(pd=pdi.current());++pdi)
908 t << "\\par " << rtf_Style_Reset << endl;
910 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
911 t << pd->getOutputFileBase();
912 t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
916 case isPageDocumentation:
918 //#error "fix me in the same way as the latex index..."
919 //t << "{\\tc \\v " << theTranslator->trPageDocumentation() << "}"<< endl;
921 //PageSDict::Iterator pdi(*Doxygen::pageSDict);
922 //PageDef *pd=pdi.toFirst();
924 //for (pdi.toFirst();(pd=pdi.current());++pdi)
926 // if (!pd->getGroupDef() && !pd->isReference())
928 // if (first) t << "\\par " << rtf_Style_Reset << endl;
929 // t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
930 // t << pd->getOutputFileBase();
931 // t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
937 case isPageDocumentation2:
940 t << "\\par " << rtf_Style_Reset << endl;
945 t << rtf_Style["Heading1"]->reference;
946 t << theTranslator->trRTFGeneralIndex() << "\\par "<< endl;
947 t << rtf_Style_Reset << endl;
948 t << "{\\tc \\v " << theTranslator->trRTFGeneralIndex() << "}" << endl;
949 t << "{\\field\\fldedit {\\*\\fldinst INDEX \\\\c2 \\\\*MERGEFORMAT}{\\fldrslt INDEX}}\n";
955 void RTFGenerator::writePageLink(const char *name,bool first)
957 if (first) t << "\\par " << rtf_Style_Reset << endl;
958 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
960 t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
963 void RTFGenerator::lastIndexPage()
965 DBG_RTF(t <<"{\\comment Beginning Body of RTF Document}\n")
966 // end page and setup for rest of document
967 t <<"\\sect \\sbkpage \\pgndec \\pgnrestart\n";
968 t <<"\\sect \\sectd \\sbknone\n";
970 // set new footer with arabic numbers
971 t <<"{\\footer "<< rtf_Style["Footer"]->reference << "{\\chpgn}}\n";
972 //t << rtf_Style["Heading1"]->reference << "\n";
976 void RTFGenerator::writeStyleInfo(int)
980 void RTFGenerator::lineBreak(const char *)
982 DBG_RTF(t << "{\\comment (lineBreak)}" << endl)
983 t << "\\par" << endl;
984 m_omitParagraph = TRUE;
987 void RTFGenerator::writeString(const char *text)
992 void RTFGenerator::startIndexList()
994 DBG_RTF(t << "{\\comment (startIndexList)}" << endl)
996 t << "\\par" << endl;
997 incrementIndentLevel();
998 t << rtf_Style_Reset << rtf_LCList_DepthStyle() << endl;
999 m_omitParagraph = TRUE;
1002 void RTFGenerator::endIndexList()
1004 DBG_RTF(t << "{\\comment (endIndexList)}" << endl)
1005 if (!m_omitParagraph)
1008 m_omitParagraph = TRUE;
1011 decrementIndentLevel();
1014 /*! start bullet list */
1015 void RTFGenerator::startItemList()
1018 DBG_RTF(t << "{\\comment (startItemList level=" << m_listLevel << ") }" << endl)
1020 incrementIndentLevel();
1021 rtf_listItemInfo[m_listLevel].isEnum = FALSE;
1024 /*! end bullet list */
1025 void RTFGenerator::endItemList()
1028 DBG_RTF(t << "{\\comment (endItemList level=" << m_listLevel << ")}" << endl)
1030 decrementIndentLevel();
1031 m_omitParagraph = TRUE;
1034 ///*! start enumeration list */
1035 //void RTFGenerator::startEnumList() // starts an enumeration list
1037 // DBG_RTF(t << "{\\comment (startEnumList)}" << endl)
1038 // t << "{" << endl;
1039 // incrementIndentLevel();
1040 // rtf_listItemInfo[m_listLevel].isEnum = TRUE;
1041 // rtf_listItemInfo[m_listLevel].number = 1;
1044 ///*! end enumeration list */
1045 //void RTFGenerator::endEnumList()
1048 // DBG_RTF(t << "{\\comment (endEnumList)}" << endl)
1050 // decrementIndentLevel();
1051 // m_omitParagraph = TRUE;
1054 /*! write bullet or enum item */
1055 void RTFGenerator::startItemListItem()
1057 DBG_RTF(t << "{\\comment (startItemListItem)}" << endl)
1059 t << rtf_Style_Reset;
1060 if (rtf_listItemInfo[m_listLevel].isEnum)
1062 t << rtf_EList_DepthStyle() << endl;
1063 t << rtf_listItemInfo[m_listLevel].number << ".\\tab ";
1064 rtf_listItemInfo[m_listLevel].number++;
1068 t << rtf_BList_DepthStyle() << endl;
1070 m_omitParagraph = TRUE;
1073 void RTFGenerator::endItemListItem()
1075 DBG_RTF(t << "{\\comment (endItemListItem)}" << endl)
1078 void RTFGenerator::startIndexItem(const char *,const char *)
1080 DBG_RTF(t << "{\\comment (startIndexItem)}" << endl)
1082 if (!m_omitParagraph)
1084 t << "\\par" << endl;
1085 m_omitParagraph = TRUE;
1089 void RTFGenerator::endIndexItem(const char *ref,const char *fn)
1091 DBG_RTF(t << "{\\comment (endIndexItem)}" << endl)
1095 writeRTFReference(fn);
1102 m_omitParagraph = TRUE;
1105 //void RTFGenerator::writeIndexFileItem(const char *,const char *text)
1107 // t << "\\item\\contentsline{section}{";
1109 // t << "}{\\pageref{" << text << "}}" << endl;
1112 void RTFGenerator::startHtmlLink(const char *url)
1115 if (Config_getBool(RTF_HYPERLINKS))
1117 t << "{\\field {\\*\\fldinst { HYPERLINK \"";
1120 t << "}{\\fldrslt {\\cs37\\ul\\cf2 ";
1128 void RTFGenerator::endHtmlLink()
1130 if (Config_getBool(RTF_HYPERLINKS))
1140 //void RTFGenerator::writeMailLink(const char *url)
1142 // startTypewriter();
1147 void RTFGenerator::writeStartAnnoItem(const char *,const char *f,
1148 const char *path,const char *name)
1150 DBG_RTF(t << "{\\comment (writeStartAnnoItem)}" << endl)
1152 if (path) docify(path);
1153 if (f && Config_getBool(RTF_HYPERLINKS))
1155 t << "{\\field {\\*\\fldinst { HYPERLINK \\\\l \"";
1156 t << rtfFormatBmkStr(f);
1158 t << "}{\\fldrslt {\\cs37\\ul\\cf2 ";
1171 void RTFGenerator::writeEndAnnoItem(const char *name)
1173 DBG_RTF(t << "{\\comment (writeEndAnnoItem)}" << endl)
1177 writeRTFReference(name);
1187 void RTFGenerator::startIndexKey()
1189 DBG_RTF(t << "{\\comment (startIndexKey)}" << endl)
1193 void RTFGenerator::endIndexKey()
1195 DBG_RTF(t << "{\\comment (endIndexKey)}" << endl)
1198 void RTFGenerator::startIndexValue(bool hasBrief)
1200 DBG_RTF(t << "{\\comment (startIndexValue)}" << endl)
1202 if (hasBrief) t << "(";
1205 void RTFGenerator::endIndexValue(const char *name,bool hasBrief)
1207 DBG_RTF(t << "{\\comment (endIndexValue)}" << endl)
1208 if (hasBrief) t << ")";
1213 writeRTFReference(name);
1220 m_omitParagraph=FALSE;
1224 void RTFGenerator::startSubsection()
1226 //beginRTFSubSection();
1228 DBG_RTF(t << "{\\comment Begin SubSection}\n")
1229 t << rtf_Style_Reset;
1230 t << rtf_Style["Heading3"]->reference << "\n";
1233 void RTFGenerator::endSubsection()
1236 t << rtf_Style_Reset << endl;
1239 void RTFGenerator::startSubsubsection()
1241 //beginRTFSubSubSection();
1243 DBG_RTF(t << "{\\comment Begin SubSubSection}\n")
1245 t << rtf_Style_Reset << rtf_Style["Heading4"]->reference << "\n";
1248 void RTFGenerator::endSubsubsection()
1255 //void RTFGenerator::writeClassLink(const char *,const char *,
1256 // const char *,const char *name)
1263 //void RTFGenerator::startTable(bool,int colNumbers)
1265 // DBG_RTF(t << "{\\comment startTable}\n";)
1266 // m_numCols=colNumbers;
1270 //void RTFGenerator::endTable(bool hasCaption)
1272 // DBG_RTF(t << "{\\comment endTable}\n";)
1274 // t << "\n\\pard \\widctlpar\\intbl\\adjustright\n{\\row }\n";
1275 // t << "\\pard\n" << endl;
1278 //void RTFGenerator::startCaption()
1280 // DBG_RTF(t << "{\\comment startCaption}\n";)
1282 // t << "\\trowd \\trgaph108\\trleft-108\\trbrdrt\\brdrs\\brdrw10 \\trbrdrl\\brdrs\\brdrw10 \\trbrdrb\\brdrs\\brdrw10 \\trbrdrr\\brdrs\\brdrw10 \\trbrdrh\\brdrs\\brdrw10 \\trbrdrv\\brdrs\\brdrw10" << endl;
1283 // t << "\\clvertalt\\clbrdrt\\brdrs\\brdrw10 \\clbrdrl\\brdrs\\brdrw10 \\clbrdrb\\brdrs\\brdrw10 \\clbrdrr \\brdrs\\brdrw10 \\cltxlrtb \\cellx"<<rtf_pageWidth<<"\\pard \\qc\\nowidctlpar\\widctlpar\\intbl\\adjustright " << endl;
1284 // nextTableColumn();
1287 //void RTFGenerator::endCaption()
1289 // DBG_RTF(t << "{\\comment endCaption}\n";)
1290 // endTableColumn();
1294 //void RTFGenerator::nextTableRow()
1296 // DBG_RTF(t << "{\\comment nextTableRow}\n";)
1297 // ASSERT(m_numCols>0 && m_numCols<25);
1298 // uint columnWidth=rtf_pageWidth/m_numCols;
1299 // t << "\\trowd \\trgaph108\\trleft-108\\trbrdrt\\brdrs\\brdrw10 "
1300 // "\\trbrdrl\\brdrs\\brdrw10 \\trbrdrb\\brdrs\\brdrw10 "
1301 // "\\trbrdrr\\brdrs\\brdrw10 \\trbrdrh\\brdrs\\brdrw10 "
1302 // "\\trbrdrv\\brdrs\\brdrw10 "<<endl;
1303 // for (int i=0;i<m_numCols;i++)
1305 // t << "\\clvertalt\\clbrdrt\\brdrs\\brdrw10 \\clbrdrl\\brdrs\\brdrw10 "
1306 // "\\clbrdrb\\brdrs\\brdrw10 \\clbrdrr \\brdrs\\brdrw10 \\cltxlrtb "
1307 // "\\cellx" << (i*columnWidth) << endl;
1309 // t << "\\pard \\widctlpar\\intbl\\adjustright\n{";
1312 //void RTFGenerator::endTableRow()
1314 // DBG_RTF(t << "{\\comment endTableRow}\n";)
1315 // t << "\n\\pard \\widctlpar\\intbl\\adjustright\n{\\row }\n";
1318 //void RTFGenerator::nextTableColumn()
1320 // DBG_RTF(t << "{\\comment nextTableColumn}\n";)
1324 //void RTFGenerator::endTableColumn()
1326 // DBG_RTF(t << "{\\comment endTableColumn}\n";)
1327 // t << " \\cell }";
1330 void RTFGenerator::startTextLink(const char *f,const char *anchor)
1332 if (Config_getBool(RTF_HYPERLINKS))
1345 t << "{\\field {\\*\\fldinst { HYPERLINK \\\\l \"";
1346 t << rtfFormatBmkStr(ref);
1348 t << "}{\\fldrslt {\\cs37\\ul\\cf2 ";
1352 void RTFGenerator::endTextLink()
1354 if (Config_getBool(RTF_HYPERLINKS))
1360 void RTFGenerator::writeObjectLink(const char *ref, const char *f,
1361 const char *anchor, const char *text)
1363 if (!ref && Config_getBool(RTF_HYPERLINKS))
1376 t << "{\\field {\\*\\fldinst { HYPERLINK \\\\l \"";
1377 t << rtfFormatBmkStr(refName);
1379 t << "}{\\fldrslt {\\cs37\\ul\\cf2 ";
1393 void RTFGenerator::startPageRef()
1399 void RTFGenerator::endPageRef(const char *clname, const char *anchor)
1411 writeRTFReference(ref);
1416 void RTFGenerator::writeCodeLink(const char *ref,const char *f,
1417 const char *anchor,const char *name,
1420 if (!ref && Config_getBool(RTF_HYPERLINKS))
1433 t << "{\\field {\\*\\fldinst { HYPERLINK \\\\l \"";
1434 t << rtfFormatBmkStr(refName);
1436 t << "}{\\fldrslt {\\cs37\\ul\\cf2 ";
1448 void RTFGenerator::startTitleHead(const char *)
1450 DBG_RTF(t <<"{\\comment startTitleHead}" << endl)
1452 // beginRTFSection();
1453 t << rtf_Style_Reset << rtf_Style["Heading2"]->reference << endl;
1456 void RTFGenerator::endTitleHead(const char *fileName,const char *name)
1458 DBG_RTF(t <<"{\\comment endTitleHead}" << endl)
1459 t << "\\par " << rtf_Style_Reset << endl;
1462 // make table of contents entry
1463 t << "{\\tc\\tcl2 \\v ";
1467 // make an index entry
1468 addIndexItem(name,0);
1472 // writeAnchor(0,name);
1475 //if (Config_getBool(RTF_HYPERLINKS) && fileName)
1477 writeAnchor(fileName,0);
1482 void RTFGenerator::startTitle()
1484 DBG_RTF(t <<"{\\comment startTitle}" << endl)
1485 if (Config_getBool(COMPACT_RTF))
1491 void RTFGenerator::startGroupHeader(int extraIndent)
1493 DBG_RTF(t <<"{\\comment startGroupHeader}" << endl)
1495 t << rtf_Style_Reset;
1498 t << rtf_Style["Heading5"]->reference;
1500 else if (extraIndent==1)
1502 t << rtf_Style["Heading4"]->reference;
1504 else // extraIndent==0
1506 t << rtf_Style["Heading3"]->reference;
1511 void RTFGenerator::endGroupHeader(int)
1513 DBG_RTF(t <<"{\\comment endGroupHeader}" << endl)
1514 t << "\\par" << endl;
1515 t << rtf_Style_Reset << endl;
1518 void RTFGenerator::startMemberDoc(const char *clname,
1519 const char *memname,
1526 DBG_RTF(t << "{\\comment startMemberDoc}" << endl)
1527 if (memname && memname[0]!='@')
1529 addIndexItem(memname,clname);
1530 addIndexItem(clname,memname);
1532 t << rtf_Style_Reset << rtf_Style[showInline ? "Heading5" : "Heading4"]->reference;
1533 //styleStack.push(rtf_Style_Heading4);
1535 //printf("RTFGenerator::startMemberDoc() `%s'\n",rtf_Style["Heading4"]->reference);
1540 void RTFGenerator::endMemberDoc(bool)
1542 DBG_RTF(t << "{\\comment endMemberDoc}" << endl)
1543 //const char *style = styleStack.pop();
1544 //printf("RTFGenerator::endMemberDoc() `%s'\n",style);
1545 //ASSERT(style==rtf_Style["Heading4"]->reference);
1551 void RTFGenerator::startDoxyAnchor(const char *,const char *,
1552 const char *,const char *,
1556 DBG_RTF(t << "{\\comment startDoxyAnchor}" << endl)
1559 void RTFGenerator::endDoxyAnchor(const char *fName,const char *anchor)
1572 DBG_RTF(t << "{\\comment endDoxyAnchor}" << endl)
1573 t << "{\\bkmkstart ";
1574 t << rtfFormatBmkStr(ref);
1577 t << rtfFormatBmkStr(ref);
1582 //void RTFGenerator::writeLatexLabel(const char *clName,const char *anchor)
1584 // writeDoxyAnchor(0,clName,anchor,0);
1587 void RTFGenerator::addIndexItem(const char *s1,const char *s2)
1602 void RTFGenerator::startIndent()
1604 incrementIndentLevel();
1605 DBG_RTF(t << "{\\comment (startIndent) }" << endl)
1607 t << rtf_Style_Reset << rtf_CList_DepthStyle() << endl;
1610 void RTFGenerator::endIndent()
1613 decrementIndentLevel();
1617 void RTFGenerator::startDescription()
1619 DBG_RTF(t << "{\\comment (startDescription)}" << endl)
1621 t << rtf_Style_Reset << rtf_DList_DepthStyle();
1624 void RTFGenerator::endDescription()
1626 DBG_RTF(t << "{\\comment (endDescription)}" << endl)
1631 void RTFGenerator::startDescItem()
1634 DBG_RTF(t << "{\\comment (startDescItem)}" << endl)
1638 void RTFGenerator::endDescItem()
1640 DBG_RTF(t << "{\\comment (endDescItem)}" << endl)
1645 void RTFGenerator::startMemberDescription(const char *,const char *,bool)
1647 DBG_RTF(t << "{\\comment (startMemberDescription)}" << endl)
1649 incrementIndentLevel();
1650 t << rtf_Style_Reset << rtf_CList_DepthStyle();
1654 void RTFGenerator::endMemberDescription()
1656 DBG_RTF(t << "{\\comment (endMemberDescription)}" << endl)
1659 decrementIndentLevel();
1662 m_omitParagraph = TRUE;
1665 void RTFGenerator::startDescList(SectionTypes)
1667 DBG_RTF(t << "{\\comment (startDescList)}" << endl)
1668 t << "{"; // ends at endDescList
1669 t << "{"; // ends at endDescTitle
1674 //void RTFGenerator::endDescTitle()
1676 // DBG_RTF(t << "{\\comment (endDescTitle) }" << endl)
1680 // incrementIndentLevel();
1681 // t << rtf_Style_Reset << rtf_DList_DepthStyle();
1684 void RTFGenerator::startDescForItem()
1686 DBG_RTF(t << "{\\comment (startDescForItem) }" << endl)
1689 void RTFGenerator::endDescForItem()
1691 DBG_RTF(t << "{\\comment (endDescForItem) }" << endl)
1694 //void RTFGenerator::endDescList()
1696 // DBG_RTF(t << "{\\comment (endDescList)}" << endl)
1698 // decrementIndentLevel();
1699 // m_omitParagraph = TRUE;
1704 void RTFGenerator::startSection(const char *,const char *title,SectionInfo::SectionType type)
1706 DBG_RTF(t << "{\\comment (startSection)}" << endl)
1708 t<< rtf_Style_Reset;
1712 case SectionInfo::Page: num=2; break;
1713 case SectionInfo::Section: num=3; break;
1714 case SectionInfo::Subsection: num=4; break;
1715 case SectionInfo::Subsubsection: num=4; break;
1716 case SectionInfo::Paragraph: num=4; break;
1717 default: ASSERT(0); break;
1720 heading.sprintf("Heading%d",num);
1722 t << rtf_Style[heading]->reference;
1723 // make table of contents entry
1724 t << "{\\tc\\tcl" << num << " \\v ";
1729 void RTFGenerator::endSection(const char *lab,SectionInfo::SectionType)
1731 DBG_RTF(t << "{\\comment (endSection)}" << endl)
1733 m_omitParagraph=FALSE;
1739 //void RTFGenerator::writeSectionRef(const char *ref,const char *,
1740 // const char *lab,const char *title)
1752 // docify(theTranslator->trPageAbbreviation());
1753 // writeRTFReference(lab);
1754 // t << ")" << endl;
1758 //void RTFGenerator::writeSectionRefItem(const char *,const char *lab,
1759 // const char *title)
1763 // writeRTFReference(lab);
1767 //void RTFGenerator::writeSectionRefAnchor(const char *name,const char *lab,
1768 // const char *title)
1770 // writeSectionRef(name,lab,title);
1773 //char* RTFGenerator::getMultiByte(int c)
1775 // static char s[10];
1777 // sprintf(s,"\\'%X",c);
1781 void RTFGenerator::docify(const char *str)
1785 const unsigned char *p=(const unsigned char *)str;
1787 //unsigned char pc='\0';
1790 //static bool MultiByte = FALSE;
1796 t << getMultiByte( c );
1803 t << getMultiByte( c );
1810 case '{': t << "\\{"; break;
1811 case '}': t << "\\}"; break;
1812 case '\\': t << "\\\\"; break;
1815 // see if we can insert an hyphenation hint
1816 //if (isupper(c) && islower(pc) && !insideTabbing) t << "\\-";
1821 m_omitParagraph = FALSE;
1826 void RTFGenerator::codify(const char *str)
1828 // note that RTF does not have a "verbatim", so "\n" means
1829 // nothing... add a "newParagraph()";
1830 //static char spaces[]=" ";
1833 const unsigned char *p=(const unsigned char *)str;
1835 int spacesToNextTabStop;
1839 //static bool MultiByte = FALSE;
1845 case '\t': spacesToNextTabStop = Config_getInt(TAB_SIZE) - (col%Config_getInt(TAB_SIZE));
1846 t << Doxygen::spaces.left(spacesToNextTabStop);
1847 col+=spacesToNextTabStop;
1849 case '\n': newParagraph();
1852 case '{': t << "\\{"; col++; break;
1853 case '}': t << "\\}"; col++; break;
1854 case '\\': t << "\\\\"; col++; break;
1855 default: p=(const unsigned char *)writeUtf8Char(t,(const char *)p-1); col++; break;
1861 void RTFGenerator::writeChar(char c)
1869 void RTFGenerator::startClassDiagram()
1871 DBG_RTF(t <<"{\\comment startClassDiagram }" << endl)
1874 void RTFGenerator::endClassDiagram(const ClassDiagram &d,
1875 const char *fileName,const char *)
1879 // create a png file
1880 d.writeImage(t,dir,relPath,fileName,FALSE);
1884 t << rtf_Style_Reset << endl;
1885 t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
1886 t << fileName << ".png\"";
1887 t << " \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
1891 //void RTFGenerator::writeFormula(const char *,const char *text)
1896 void RTFGenerator::startMemberItem(const char *,int,const char *)
1898 DBG_RTF(t <<"{\\comment startMemberItem }" << endl)
1899 t << rtf_Style_Reset << rtf_BList_DepthStyle() << endl; // set style to appropriate depth
1902 void RTFGenerator::endMemberItem()
1904 DBG_RTF(t <<"{\\comment endMemberItem }" << endl)
1908 void RTFGenerator::writeAnchor(const char *fileName,const char *name)
1915 if (fileName && name)
1924 DBG_RTF(t <<"{\\comment writeAnchor (" << anchor << ")}" << endl)
1925 t << "{\\bkmkstart " << rtfFormatBmkStr(anchor) << "}" << endl;
1926 t << "{\\bkmkend " << rtfFormatBmkStr(anchor) << "}" << endl;
1929 void RTFGenerator::writeRTFReference(const char *label)
1931 t << "{\\field\\fldedit {\\*\\fldinst PAGEREF ";
1932 t << rtfFormatBmkStr(label);
1933 t << " \\\\*MERGEFORMAT}{\\fldrslt pagenum}}";
1936 void RTFGenerator::startCodeFragment()
1938 DBG_RTF(t << "{\\comment (startCodeFragment) }" << endl)
1941 t << rtf_Style_Reset << rtf_Code_DepthStyle();
1942 //styleStack.push(rtf_Style_CodeExample);
1945 void RTFGenerator::endCodeFragment()
1949 //printf("RTFGenerator::endCodeFrament() top=%s\n",styleStack.top());
1950 //t << rtf_Style_Reset << styleStack.top() << endl;
1951 DBG_RTF(t << "{\\comment (endCodeFragment) }" << endl)
1953 m_omitParagraph = TRUE;
1956 void RTFGenerator::writeNonBreakableSpace(int)
1962 void RTFGenerator::startMemberList()
1965 DBG_RTF(t << "{\\comment (startMemberList) }" << endl)
1969 t << "\\begin{CompactItemize}" << endl;
1973 void RTFGenerator::endMemberList()
1975 DBG_RTF(t << "{\\comment (endMemberList) }" << endl)
1979 t << "\\end{CompactItemize}" << endl;
1983 //void RTFGenerator::startImage(const char *name,const char *,bool)
1986 // t << "{" << endl;
1987 // t << rtf_Style_Reset << endl;
1988 // t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE ";
1990 // t << " \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
1991 // t << "}" << endl;
1994 //void RTFGenerator::endImage(bool)
1996 // // not yet implemented
1999 //void RTFGenerator::startDotFile(const char *name,bool)
2001 // QCString baseName=name;
2003 // if ((i=baseName.findRev('/'))!=-1 || (i=baseName.findRev('\\'))!=-1)
2005 // baseName=baseName.right(baseName.length()-i-1);
2007 // QCString outDir = Config_getString(RTF_OUTPUT);
2008 // writeDotGraphFromFile(name,outDir,baseName,BITMAP);
2010 // t << "{" << endl;
2011 // t << rtf_Style_Reset << endl;
2012 // t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE ";
2013 // t << outDir << "\\" << baseName;
2014 // t << " \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
2015 // t << "}" << endl;
2018 //void RTFGenerator::endDotFile(bool)
2020 // // not yet implemented
2023 void RTFGenerator::startDescTable(const char *title)
2025 DBG_RTF(t << "{\\comment (startDescTable) }" << endl)
2026 t << "{\\par" << endl;
2027 t << "{" << rtf_Style["Heading5"]->reference << endl;
2029 t << ":\\par}" << endl;
2030 t << rtf_Style_Reset << rtf_DList_DepthStyle();
2031 t << "\\trowd \\trgaph108\\trleft426\\tblind426"
2032 "\\trbrdrt\\brdrs\\brdrw10\\brdrcf15 "
2033 "\\trbrdrl\\brdrs\\brdrw10\\brdrcf15 "
2034 "\\trbrdrb\\brdrs\\brdrw10\\brdrcf15 "
2035 "\\trbrdrr\\brdrs\\brdrw10\\brdrcf15 "
2036 "\\trbrdrh\\brdrs\\brdrw10\\brdrcf15 "
2037 "\\trbrdrv\\brdrs\\brdrw10\\brdrcf15 "<< endl;
2038 int i,columnPos[2] = { 25, 100 };
2041 t << "\\clvertalt\\clbrdrt\\brdrs\\brdrw10\\brdrcf15 "
2042 "\\clbrdrl\\brdrs\\brdrw10\\brdrcf15 "
2043 "\\clbrdrb\\brdrs\\brdrw10\\brdrcf15 "
2044 "\\clbrdrr \\brdrs\\brdrw10\\brdrcf15 "
2046 "\\cellx" << (rtf_pageWidth*columnPos[i]/100) << endl;
2048 t << "\\pard \\widctlpar\\intbl\\adjustright" << endl;
2051 void RTFGenerator::endDescTable()
2053 DBG_RTF(t << "{\\comment (endDescTable)}" << endl)
2057 void RTFGenerator::startDescTableRow()
2061 void RTFGenerator::endDescTableRow()
2065 void RTFGenerator::startDescTableTitle()
2067 DBG_RTF(t << "{\\comment (startDescTableTitle) }" << endl)
2071 void RTFGenerator::endDescTableTitle()
2073 DBG_RTF(t << "{\\comment (endDescTableTitle) }" << endl)
2077 void RTFGenerator::startDescTableData()
2079 DBG_RTF(t << "{\\comment (startDescTableData) }" << endl)
2083 void RTFGenerator::endDescTableData()
2085 DBG_RTF(t << "{\\comment (endDescTableData) }" << endl)
2086 t << "\\cell }{\\row }" << endl;
2089 // a style for list formatted as a "bulleted list"
2091 void RTFGenerator::incrementIndentLevel()
2094 if (m_listLevel>rtf_maxIndentLevels-1)
2096 err("Maximum indent level (%d) exceeded while generating RTF output!\n",rtf_maxIndentLevels);
2097 m_listLevel=rtf_maxIndentLevels-1;
2101 void RTFGenerator::decrementIndentLevel()
2106 err("Negative indent level while generating RTF output!\n");
2111 // a style for list formatted with "list continue" style
2112 const char * RTFGenerator::rtf_CList_DepthStyle()
2114 QCString n=makeIndexName("ListContinue",m_listLevel);
2115 return rtf_Style[n]->reference;
2118 // a style for list formatted as a "latext style" table of contents
2119 const char * RTFGenerator::rtf_LCList_DepthStyle()
2121 QCString n=makeIndexName("LatexTOC",m_listLevel);
2122 return rtf_Style[n]->reference;
2125 // a style for list formatted as a "bullet" style
2126 const char * RTFGenerator::rtf_BList_DepthStyle()
2128 QCString n=makeIndexName("ListBullet",m_listLevel);
2129 return rtf_Style[n]->reference;
2132 // a style for list formatted as a "enumeration" style
2133 const char * RTFGenerator::rtf_EList_DepthStyle()
2135 QCString n=makeIndexName("ListEnum",m_listLevel);
2136 return rtf_Style[n]->reference;
2139 const char * RTFGenerator::rtf_DList_DepthStyle()
2141 QCString n=makeIndexName("DescContinue",m_listLevel);
2142 return rtf_Style[n]->reference;
2145 const char * RTFGenerator::rtf_Code_DepthStyle()
2147 QCString n=makeIndexName("CodeExample",m_listLevel);
2148 return rtf_Style[n]->reference;
2151 void RTFGenerator::startTextBlock(bool dense)
2153 DBG_RTF(t << "{\\comment startTextBlock}" << endl)
2155 t << rtf_Style_Reset;
2156 if (dense) // no spacing between "paragraphs"
2158 t << rtf_Style["DenseText"]->reference;
2160 else // some spacing
2162 t << rtf_Style["BodyText"]->reference;
2166 void RTFGenerator::endTextBlock(bool /*paraBreak*/)
2169 DBG_RTF(t << "{\\comment endTextBlock}" << endl)
2171 //m_omitParagraph = TRUE;
2174 void RTFGenerator::newParagraph()
2176 if (!m_omitParagraph)
2178 DBG_RTF(t << "{\\comment (newParagraph)}" << endl)
2179 t << "\\par" << endl;
2181 m_omitParagraph = FALSE;
2184 void RTFGenerator::startParagraph(const char *txt)
2186 DBG_RTF(t << "{\\comment startParagraph}" << endl)
2189 if (QCString(txt) == "reference") t << "\\ql" << endl;
2192 void RTFGenerator::endParagraph()
2194 DBG_RTF(t << "{\\comment endParagraph}" << endl)
2195 t << "}\\par" << endl;
2196 m_omitParagraph = TRUE;
2199 void RTFGenerator::startMemberSubtitle()
2201 DBG_RTF(t << "{\\comment startMemberSubtitle}" << endl)
2203 t << rtf_Style_Reset << rtf_CList_DepthStyle() << endl;
2206 void RTFGenerator::endMemberSubtitle()
2208 DBG_RTF(t << "{\\comment endMemberSubtitle}" << endl)
2213 //void RTFGenerator::writeUmlaut(char c)
2217 // case 'A' : t << '\304'; break;
2218 // case 'E' : t << '\313'; break;
2219 // case 'I' : t << '\317'; break;
2220 // case 'O' : t << '\326'; break;
2221 // case 'U' : t << '\334'; break;
2222 // case 'Y' : t << 'Y'; break;
2223 // case 'a' : t << '\344'; break;
2224 // case 'e' : t << '\353'; break;
2225 // case 'i' : t << '\357'; break;
2226 // case 'o' : t << '\366'; break;
2227 // case 'u' : t << '\374'; break;
2228 // case 'y' : t << '\377'; break;
2229 // default: t << '?'; break;
2233 //void RTFGenerator::writeAcute(char c)
2237 // case 'A' : t << '\301'; break;
2238 // case 'E' : t << '\311'; break;
2239 // case 'I' : t << '\315'; break;
2240 // case 'O' : t << '\323'; break;
2241 // case 'U' : t << '\332'; break;
2242 // case 'Y' : t << '\335'; break;
2243 // case 'a' : t << '\341'; break;
2244 // case 'e' : t << '\351'; break;
2245 // case 'i' : t << '\355'; break;
2246 // case 'o' : t << '\363'; break;
2247 // case 'u' : t << '\372'; break;
2248 // case 'y' : t << '\375'; break;
2249 // default: t << '?'; break;
2253 //void RTFGenerator::writeGrave(char c)
2257 // case 'A' : t << '\300'; break;
2258 // case 'E' : t << '\310'; break;
2259 // case 'I' : t << '\314'; break;
2260 // case 'O' : t << '\322'; break;
2261 // case 'U' : t << '\331'; break;
2262 // case 'a' : t << '\340'; break;
2263 // case 'e' : t << '\350'; break;
2264 // case 'i' : t << '\354'; break;
2265 // case 'o' : t << '\362'; break;
2266 // case 'u' : t << '\371'; break;
2267 // default: t << '?'; break;
2271 //void RTFGenerator::writeCirc(char c)
2275 // case 'A' : t << '\302'; break;
2276 // case 'E' : t << '\312'; break;
2277 // case 'I' : t << '\316'; break;
2278 // case 'O' : t << '\324'; break;
2279 // case 'U' : t << '\333'; break;
2280 // case 'a' : t << '\342'; break;
2281 // case 'e' : t << '\352'; break;
2282 // case 'i' : t << '\356'; break;
2283 // case 'o' : t << '\364'; break;
2284 // case 'u' : t << '\373'; break;
2285 // default: t << '?'; break;
2289 //void RTFGenerator::writeTilde(char c)
2293 // case 'A' : t << '\303'; break;
2294 // case 'N' : t << '\321'; break;
2295 // case 'O' : t << '\325'; break;
2296 // case 'a' : t << '\343'; break;
2297 // case 'n' : t << '\361'; break;
2298 // case 'o' : t << '\365'; break;
2299 // default: t << '?'; break;
2303 //void RTFGenerator::writeRing(char c)
2307 // case 'A' : t << '\305'; break;
2308 // case 'a' : t << '\345'; break;
2309 // default: t << '?'; break;
2313 //void RTFGenerator::writeCCedil(char c)
2317 // case 'C' : t << '\307'; break;
2318 // case 'c' : t << '\347'; break;
2319 // default: t << '?'; break;
2324 bool isLeadBytes(int c)
2328 QCString codePage = theTranslator->trRTFansicp();
2330 if (codePage == "932") // cp932 (Japanese Shift-JIS)
2332 result = (0x81<=c && c<=0x9f) || (0xe0<=c && c<=0xfc);
2334 else if (codePage == "936") // cp936 (Simplified Chinese GBK)
2336 result = 0x81<=c && c<=0xFE;
2338 else if (codePage == "949") // cp949 (Korean)
2340 result = 0x81<=c && c<=0xFE;
2342 else if (codePage == "950") // cp950 (Traditional Chinese Big5)
2344 result = 0x81<=c && c<=0xFE;
2346 else // for SBCS Codepages (cp1252,1251 etc...)
2355 // note: function is not reentrant!
2356 static void encodeForOutput(FTextStream &t,const char *s)
2360 bool converted=FALSE;
2362 static QByteArray enc;
2363 if (l*4>(int)enc.size()) enc.resize(l*4); // worst case
2364 encoding.sprintf("CP%s",theTranslator->trRTFansicp().data());
2365 if (!encoding.isEmpty())
2367 // convert from UTF-8 back to the output encoding
2368 void *cd = portable_iconv_open(encoding,"UTF-8");
2369 if (cd!=(void *)(-1))
2372 size_t oLeft=enc.size();
2373 char *inputPtr = (char*)s;
2374 char *outputPtr = enc.data();
2375 if (!portable_iconv(cd, &inputPtr, &iLeft, &outputPtr, &oLeft))
2377 enc.resize(enc.size()-(unsigned int)oLeft);
2380 portable_iconv_close(cd);
2383 if (!converted) // if we did not convert anything, copy as is.
2385 memcpy(enc.data(),s,l);
2389 bool multiByte = FALSE;
2391 for (i=0;i<enc.size();i++)
2393 uchar c = (uchar)enc.at(i);
2395 if (c>=0x80 || multiByte)
2398 sprintf(esc,"\\'%X",c); // escape sequence for SBCS and DBCS(1st&2nd bytes).
2403 multiByte = isLeadBytes(c); // It may be DBCS Codepages.
2407 multiByte = FALSE; // end of Double Bytes Character.
2418 * VERY brittle routine inline RTF's included by other RTF's.
2419 * it is recursive and ugly.
2421 static bool preProcessFile(QDir &d,QCString &infName, FTextStream &t, bool bIncludeHeader=TRUE)
2424 if (!f.open(IO_ReadOnly))
2426 err("problems opening rtf file %s for reading\n",infName.data());
2430 const int maxLineLength = 10240;
2431 static QCString lineBuf(maxLineLength);
2433 // scan until find end of header
2434 // this is EXTREEEEEEEMLY brittle. It works on OUR rtf
2435 // files because the first line before the body
2436 // ALWAYS contains "{\comment begin body}"
2440 lineBuf.resize(maxLineLength);
2441 if ((len=f.readLine(lineBuf.rawData(),maxLineLength))==-1)
2443 err("read error in %s before end of RTF header!\n",infName.data());
2446 lineBuf.resize(len+1);
2447 if (lineBuf.find("\\comment begin body")!=-1) break;
2448 if (bIncludeHeader) encodeForOutput(t,lineBuf.data());
2452 lineBuf.resize(maxLineLength);
2453 while ((len=f.readLine(lineBuf.rawData(),maxLineLength))!=-1)
2455 lineBuf.resize(len+1);
2457 if ((pos=lineBuf.find("INCLUDETEXT"))!=-1)
2459 int startNamePos = lineBuf.find('"',pos)+1;
2460 int endNamePos = lineBuf.find('"',startNamePos);
2461 QCString fileName = lineBuf.mid(startNamePos,endNamePos-startNamePos);
2462 DBG_RTF(t << "{\\comment begin include " << fileName << "}" << endl)
2463 if (!preProcessFile(d,fileName,t,FALSE)) return FALSE;
2464 DBG_RTF(t << "{\\comment end include " << fileName << "}" << endl)
2466 else // no INCLUDETEXT on this line
2468 // elaborate hoopla to skip the final "}" if we didn't include the
2470 if (!f.atEnd() || bIncludeHeader)
2472 encodeForOutput(t,lineBuf);
2474 else // last line of included file
2476 // null terminate at the last '}'
2477 //char *str = strrchr(buffer,'}');
2478 int pos = lineBuf.findRev('}');
2481 lineBuf.at(pos) = '\0';
2483 err("Strange, the last char was not a '}'\n");
2484 encodeForOutput(t,lineBuf);
2487 lineBuf.resize(maxLineLength);
2490 // remove temporary file
2495 void RTFGenerator::startDotGraph()
2497 DBG_RTF(t << "{\\comment (startDotGraph)}" << endl)
2500 void RTFGenerator::endDotGraph(const DotClassGraph &g)
2505 g.writeGraph(t,GOF_BITMAP,EOF_Rtf,Config_getString(RTF_OUTPUT),fileName,relPath,TRUE,FALSE);
2509 t << rtf_Style_Reset << endl;
2510 t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
2511 QCString imgExt = getDotImageExtension();
2512 t << fn << "." << imgExt;
2513 t << "\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
2516 DBG_RTF(t << "{\\comment (endDotGraph)}" << endl)
2519 void RTFGenerator::startInclDepGraph()
2521 DBG_RTF(t << "{\\comment (startInclDepGraph)}" << endl)
2524 void RTFGenerator::endInclDepGraph(const DotInclDepGraph &g)
2528 QCString fn = g.writeGraph(t,GOF_BITMAP,EOF_Rtf,Config_getString(RTF_OUTPUT),
2529 fileName,relPath,FALSE);
2533 t << rtf_Style_Reset << endl;
2534 t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
2535 QCString imgExt = getDotImageExtension();
2536 t << fn << "." << imgExt;
2537 t << "\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
2539 DBG_RTF(t << "{\\comment (endInclDepGraph)}" << endl)
2542 void RTFGenerator::startGroupCollaboration()
2546 void RTFGenerator::endGroupCollaboration(const DotGroupCollaboration &)
2550 void RTFGenerator::startCallGraph()
2552 DBG_RTF(t << "{\\comment (startCallGraph)}" << endl)
2555 void RTFGenerator::endCallGraph(const DotCallGraph &g)
2559 QCString fn = g.writeGraph(t,GOF_BITMAP,EOF_Rtf,Config_getString(RTF_OUTPUT),
2560 fileName,relPath,FALSE);
2564 t << rtf_Style_Reset << endl;
2565 t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
2566 QCString imgExt = getDotImageExtension();
2567 t << fn << "." << imgExt;
2568 t << "\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
2570 DBG_RTF(t << "{\\comment (endCallGraph)}" << endl)
2573 void RTFGenerator::startDirDepGraph()
2575 DBG_RTF(t << "{\\comment (startDirDepGraph)}" << endl)
2578 void RTFGenerator::endDirDepGraph(const DotDirDeps &g)
2582 QCString fn = g.writeGraph(t,GOF_BITMAP,EOF_Rtf,Config_getString(RTF_OUTPUT),
2583 fileName,relPath,FALSE);
2587 t << rtf_Style_Reset << endl;
2588 t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
2589 QCString imgExt = getDotImageExtension();
2590 t << fn << "." << imgExt;
2591 t << "\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
2593 DBG_RTF(t << "{\\comment (endDirDepGraph)}" << endl)
2596 /** Tests the integrity of the result by counting brackets.
2599 void testRTFOutput(const char *name)
2605 if (f.open(IO_ReadOnly))
2607 while ((c=f.getch())!=-1)
2609 if (c=='\\') // escape char
2614 else if (c=='{') // open bracket
2618 else if (c=='}') // close bracket
2627 else if (c=='\n') // newline
2633 if (bcount==0) return; // file is OK.
2635 err("RTF integrity test failed at line %d of %s due to a bracket mismatch.\n"
2636 " Please try to create a small code example that produces this error \n"
2637 " and send that to doxygen@gmail.com.\n",line,name);
2641 * This is an API to a VERY brittle RTF preprocessor that combines nested
2642 * RTF files. This version replaces the infile with the new file
2644 bool RTFGenerator::preProcessFileInplace(const char *path,const char *name)
2647 // store the original directory
2650 err("Output dir %s does not exist!\n",path);
2653 QCString oldDir = QDir::currentDirPath().utf8();
2655 // go to the html output directory (i.e. path)
2656 QDir::setCurrent(d.absPath());
2659 QCString combinedName = (QCString)path+"/combined.rtf";
2660 QCString mainRTFName = (QCString)path+"/"+name;
2662 QFile outf(combinedName);
2663 if (!outf.open(IO_WriteOnly))
2665 err("Failed to open %s for writing!\n",combinedName.data());
2666 QDir::setCurrent(oldDir);
2669 FTextStream outt(&outf);
2671 if (!preProcessFile(thisDir,mainRTFName,outt))
2673 // it failed, remove the temp file
2675 thisDir.remove(combinedName);
2676 QDir::setCurrent(oldDir);
2680 // everything worked, move the files
2682 thisDir.remove(mainRTFName);
2683 thisDir.rename(combinedName,mainRTFName);
2685 testRTFOutput(mainRTFName);
2687 QDir::setCurrent(oldDir);
2691 void RTFGenerator::startMemberGroupHeader(bool hasHeader)
2693 DBG_RTF(t << "{\\comment startMemberGroupHeader}" << endl)
2695 if (hasHeader) incrementIndentLevel();
2696 t << rtf_Style_Reset << rtf_Style["GroupHeader"]->reference;
2699 void RTFGenerator::endMemberGroupHeader()
2701 DBG_RTF(t << "{\\comment endMemberGroupHeader}" << endl)
2703 t << rtf_Style_Reset << rtf_CList_DepthStyle();
2706 void RTFGenerator::startMemberGroupDocs()
2708 DBG_RTF(t << "{\\comment startMemberGroupDocs}" << endl)
2712 void RTFGenerator::endMemberGroupDocs()
2714 DBG_RTF(t << "{\\comment endMemberGroupDocs}" << endl)
2719 void RTFGenerator::startMemberGroup()
2721 DBG_RTF(t << "{\\comment startMemberGroup}" << endl)
2722 t << rtf_Style_Reset << rtf_BList_DepthStyle() << endl;
2725 void RTFGenerator::endMemberGroup(bool hasHeader)
2727 DBG_RTF(t << "{\\comment endMemberGroup}" << endl)
2728 if (hasHeader) decrementIndentLevel();
2732 void RTFGenerator::startExamples()
2734 DBG_RTF(t << "{\\comment (startExamples)}" << endl)
2735 t << "{"; // ends at endDescList
2736 t << "{"; // ends at endDescTitle
2739 docify(theTranslator->trExamples());
2743 incrementIndentLevel();
2744 t << rtf_Style_Reset << rtf_DList_DepthStyle();
2747 void RTFGenerator::endExamples()
2749 DBG_RTF(t << "{\\comment (endExamples)}" << endl)
2750 m_omitParagraph = FALSE;
2752 decrementIndentLevel();
2753 m_omitParagraph = TRUE;
2757 void RTFGenerator::startParamList(ParamListTypes,const char *title)
2759 DBG_RTF(t << "{\\comment (startParamList)}" << endl)
2760 t << "{"; // ends at endParamList
2761 t << "{"; // ends at endDescTitle
2768 incrementIndentLevel();
2769 t << rtf_Style_Reset << rtf_DList_DepthStyle();
2772 void RTFGenerator::endParamList()
2774 DBG_RTF(t << "{\\comment (endParamList)}" << endl)
2776 decrementIndentLevel();
2777 m_omitParagraph = TRUE;
2781 void RTFGenerator::startParameterType(bool first,const char *key)
2783 DBG_RTF(t << "{\\comment (startParameterType)}" << endl)
2786 t << " " << key << " ";
2790 void RTFGenerator::endParameterType()
2792 DBG_RTF(t << "{\\comment (endParameterType)}" << endl)
2796 void RTFGenerator::exceptionEntry(const char* prefix,bool closeBracket)
2798 DBG_RTF(t << "{\\comment (exceptionEntry)}" << endl)
2800 t << " " << prefix << "(";
2801 else if (closeBracket)
2806 void RTFGenerator::writeDoc(DocNode *n,Definition *ctx,MemberDef *)
2808 RTFDocVisitor *visitor = new RTFDocVisitor(t,*this,ctx?ctx->getDefFileExtension():QCString(""));
2811 m_omitParagraph = TRUE;
2814 void RTFGenerator::rtfwriteRuler_doubleline()
2816 DBG_RTF(t << "{\\comment (rtfwriteRuler_doubleline)}" << endl)
2817 t << "{\\pard\\widctlpar\\brdrb\\brdrdb\\brdrw15\\brsp20 \\adjustright \\par}" << endl;
2820 void RTFGenerator::rtfwriteRuler_emboss()
2822 DBG_RTF(t << "{\\comment (rtfwriteRuler_emboss)}" << endl)
2823 t << "{\\pard\\widctlpar\\brdrb\\brdremboss\\brdrw15\\brsp20 \\adjustright \\par}" << endl;
2826 void RTFGenerator::rtfwriteRuler_thick()
2828 DBG_RTF(t << "{\\comment (rtfwriteRuler_thick)}" << endl)
2829 t << "{\\pard\\widctlpar\\brdrb\\brdrs\\brdrw75\\brsp20 \\adjustright \\par}" << endl;
2832 void RTFGenerator::rtfwriteRuler_thin()
2834 DBG_RTF(t << "{\\comment (rtfwriteRuler_thin)}" << endl)
2835 t << "{\\pard\\widctlpar\\brdrb\\brdrs\\brdrw5\\brsp20 \\adjustright \\par}" << endl;
2839 void RTFGenerator::postProcess(QByteArray &a)
2841 QByteArray enc(a.size()*4); // worst case
2845 for (i=0;i<a.size();i++)
2847 unsigned char c = (unsigned char)a.at(i);
2849 // treat characters > 0x80 as multibyte characters, except when they
2850 // are control characters
2851 if (c>0x80 || (mbFlag && c!='\\' && c!='{' && c!='}'))
2854 sprintf(s,"\\'%X",c);
2855 qstrcpy(enc.data()+off,s);
2869 void RTFGenerator::startConstraintList(const char *header)
2871 DBG_RTF(t << "{\\comment (startConstraintList)}" << endl)
2872 t << "{"; // ends at endConstraintList
2880 incrementIndentLevel();
2881 t << rtf_Style_Reset << rtf_DList_DepthStyle();
2884 void RTFGenerator::startConstraintParam()
2886 DBG_RTF(t << "{\\comment (startConstraintParam)}" << endl)
2890 void RTFGenerator::endConstraintParam()
2892 DBG_RTF(t << "{\\comment (endConstraintParam)}" << endl)
2897 void RTFGenerator::startConstraintType()
2899 DBG_RTF(t << "{\\comment (startConstraintType)}" << endl)
2903 void RTFGenerator::endConstraintType()
2905 DBG_RTF(t << "{\\comment (endConstraintType)}" << endl)
2910 void RTFGenerator::startConstraintDocs()
2912 DBG_RTF(t << "{\\comment (startConstraintDocs)}" << endl)
2915 void RTFGenerator::endConstraintDocs()
2917 DBG_RTF(t << "{\\comment (endConstraintDocs)}" << endl)
2921 void RTFGenerator::endConstraintList()
2923 DBG_RTF(t << "{\\comment (endConstraintList)}" << endl)
2925 decrementIndentLevel();
2926 m_omitParagraph = TRUE;
2930 void RTFGenerator::startIndexListItem()
2932 DBG_RTF(t << "{\\comment (startIndexListItem)}" << endl)
2935 void RTFGenerator::endIndexListItem()
2937 DBG_RTF(t << "{\\comment (endIndexListItem)}" << endl)
2938 t << "\\par" << endl;
2941 void RTFGenerator::startInlineHeader()
2943 DBG_RTF(t << "{\\comment (startInlineHeader)}" << endl)
2945 t << rtf_Style_Reset << rtf_Style["Heading5"]->reference;
2949 void RTFGenerator::endInlineHeader()
2951 DBG_RTF(t << "{\\comment (endInlineHeader)}" << endl)
2957 void RTFGenerator::startMemberDocSimple(bool isEnum)
2959 DBG_RTF(t << "{\\comment (startMemberDocSimple)}" << endl)
2960 t << "{\\par" << endl;
2961 t << "{" << rtf_Style["Heading5"]->reference << endl;
2964 t << theTranslator->trEnumerationValues();
2968 t << theTranslator->trCompoundMembers();
2970 t << ":\\par}" << endl;
2971 t << rtf_Style_Reset << rtf_DList_DepthStyle();
2972 t << "\\trowd \\trgaph108\\trleft426\\tblind426"
2973 "\\trbrdrt\\brdrs\\brdrw10\\brdrcf15 "
2974 "\\trbrdrl\\brdrs\\brdrw10\\brdrcf15 "
2975 "\\trbrdrb\\brdrs\\brdrw10\\brdrcf15 "
2976 "\\trbrdrr\\brdrs\\brdrw10\\brdrcf15 "
2977 "\\trbrdrh\\brdrs\\brdrw10\\brdrcf15 "
2978 "\\trbrdrv\\brdrs\\brdrw10\\brdrcf15 "<< endl;
2979 int i,n=3,columnPos[3] = { 25, 50, 100 };
2988 t << "\\clvertalt\\clbrdrt\\brdrs\\brdrw10\\brdrcf15 "
2989 "\\clbrdrl\\brdrs\\brdrw10\\brdrcf15 "
2990 "\\clbrdrb\\brdrs\\brdrw10\\brdrcf15 "
2991 "\\clbrdrr \\brdrs\\brdrw10\\brdrcf15 "
2993 "\\cellx" << (rtf_pageWidth*columnPos[i]/100) << endl;
2995 t << "\\pard \\widctlpar\\intbl\\adjustright" << endl;
2998 void RTFGenerator::endMemberDocSimple(bool)
3000 DBG_RTF(t << "{\\comment (endMemberDocSimple)}" << endl)
3004 void RTFGenerator::startInlineMemberType()
3006 DBG_RTF(t << "{\\comment (startInlineMemberType)}" << endl)
3010 void RTFGenerator::endInlineMemberType()
3012 DBG_RTF(t << "{\\comment (endInlineMemberType)}" << endl)
3016 void RTFGenerator::startInlineMemberName()
3018 DBG_RTF(t << "{\\comment (startInlineMemberName)}" << endl)
3022 void RTFGenerator::endInlineMemberName()
3024 DBG_RTF(t << "{\\comment (endInlineMemberName)}" << endl)
3028 void RTFGenerator::startInlineMemberDoc()
3030 DBG_RTF(t << "{\\comment (startInlineMemberDoc)}" << endl)
3034 void RTFGenerator::endInlineMemberDoc()
3036 DBG_RTF(t << "{\\comment (endInlineMemberDoc)}" << endl)
3037 t << "\\cell }{\\row }" << endl;
3040 void RTFGenerator::startLabels()
3044 void RTFGenerator::writeLabel(const char *l,bool isLast)
3046 t << "{\\f2 [" << l << "]}";
3047 if (!isLast) t << ", ";
3050 void RTFGenerator::endLabels()
3054 void RTFGenerator::startFontClass(const char *name)
3057 QCString qname(name);
3058 if (qname == "keyword") cod = 17;
3059 else if (qname == "keywordtype") cod = 18;
3060 else if (qname == "keywordflow") cod = 19;
3061 else if (qname == "comment") cod = 20;
3062 else if (qname == "preprocessor") cod = 21;
3063 else if (qname == "stringliteral") cod = 22;
3064 else if (qname == "charliteral") cod = 23;
3065 else if (qname == "vhdldigit") cod = 24;
3066 else if (qname == "vhdlchar") cod = 25;
3067 else if (qname == "vhdlkeyword") cod = 26;
3068 else if (qname == "vhdllogic") cod = 27;
3069 t << "{\\cf" << cod << " ";
3072 void RTFGenerator::endFontClass()