1 /****************************************************************************** 2 * 3 * 4 * 5 * 6 * Copyright (C) 1997-2015 by Dimitri van Heesch. 7 * 8 * Permission to use, copy, modify, and distribute this software and its 9 * documentation under the terms of the GNU General Public License is hereby 10 * granted. No representations are made about the suitability of this software 11 * for any purpose. It is provided "as is" without express or implied warranty. 12 * See the GNU General Public License for more details. 13 * 14 * Documents produced by Doxygen are derivative works derived from the 15 * input used in their production; they are not affected by this license. 16 * 17 */ 18 19 #ifndef DOCPARSER_H 20 #define DOCPARSER_H 21 22 #include <stdio.h> 23 #include <vector> 24 #include <memory> 25 26 #include "qcstring.h" 27 #include "docvisitor.h" 28 #include "htmlattrib.h" 29 30 class DocNode; 31 class MemberDef; 32 class Definition; 33 class MemberGroup; 34 35 //--------------------------------------------------------------------------- 36 37 // forward declared, opaque pointer 38 class IDocParser 39 { 40 public: ~IDocParser()41 virtual ~IDocParser() {} 42 }; 43 44 // factory function 45 std::unique_ptr<IDocParser> createDocParser(); 46 47 //--------------------------------------------------------------------------- 48 49 /*! Main entry point for the documentation parser. 50 * @param parser The parser object created via createDocParser() 51 * @param fileName File in which the documentation block is found (or the 52 * name of the example file in case isExample is TRUE). 53 * @param startLine Line at which the documentation block is found. 54 * @param context Class or namespace to which this block belongs. 55 * @param md Member definition to which the documentation belongs. 56 * Can be 0. 57 * @param input String representation of the documentation block. 58 * @param indexWords Indicates whether or not words should be put in the 59 * search index. 60 * @param isExample TRUE if the documentation belongs to an example. 61 * @param exampleName Base name of the example file (0 if isExample is FALSE). 62 * @param singleLine Output should be presented on a single line, so without 63 * starting a new paragraph at the end. 64 * @param linkFromIndex TRUE if the documentation is generated from an 65 * index page. In this case context is not used to determine 66 * the relative path when making a link. 67 * @param markdownSupport TRUE if the input needs to take markdown markup into 68 * account. 69 * @returns Root node of the abstract syntax tree. Ownership of the 70 * pointer is handed over to the caller. 71 */ 72 DocRoot *validatingParseDoc(IDocParser &parser,const QCString &fileName,int startLine, 73 const Definition *context, const MemberDef *md, 74 const QCString &input,bool indexWords, 75 bool isExample,const QCString &exampleName, 76 bool singleLine,bool linkFromIndex, 77 bool markdownSupport); 78 79 /*! Main entry point for parsing simple text fragments. These 80 * fragments are limited to words, whitespace and symbols. 81 */ 82 DocText *validatingParseText(IDocParser &parser,const QCString &input); 83 84 /*! Searches for section and anchor commands in the input */ 85 void docFindSections(const QCString &input, 86 const Definition *d, 87 const QCString &fileName); 88 89 DocRef *createRef(IDocParser &parser,const QCString &target,const QCString &context); 90 91 //-------------------------------------------------------------------------------- 92 93 class DocParser; 94 95 /** Abstract node interface with type information. */ 96 class DocNode 97 { 98 public: 99 /*! Available node types. */ 100 enum Kind { Kind_Root = 0, 101 Kind_Word = 1, 102 Kind_WhiteSpace = 2, 103 Kind_Para = 3, 104 Kind_AutoList = 4, 105 Kind_AutoListItem = 5, 106 Kind_Symbol = 6, 107 Kind_URL = 7, 108 Kind_StyleChange = 8, 109 Kind_SimpleSect = 9, 110 Kind_Title = 10, 111 Kind_SimpleList = 11, 112 Kind_SimpleListItem = 12, 113 Kind_Section = 13, 114 Kind_Verbatim = 14, 115 Kind_XRefItem = 15, 116 Kind_HtmlList = 16, 117 Kind_HtmlListItem = 17, 118 Kind_HtmlDescList = 18, 119 Kind_HtmlDescData = 19, 120 Kind_HtmlDescTitle = 20, 121 Kind_HtmlTable = 21, 122 Kind_HtmlRow = 22, 123 Kind_HtmlCell = 23, 124 Kind_HtmlCaption = 24, 125 Kind_LineBreak = 25, 126 Kind_HorRuler = 26, 127 Kind_Anchor = 27, 128 Kind_IndexEntry = 28, 129 Kind_Internal = 29, 130 Kind_HRef = 30, 131 Kind_Include = 31, 132 Kind_IncOperator = 32, 133 Kind_HtmlHeader = 33, 134 Kind_Image = 34, 135 Kind_DotFile = 35, 136 Kind_Link = 36, 137 Kind_Ref = 37, 138 Kind_Formula = 38, 139 Kind_SecRefItem = 39, 140 Kind_SecRefList = 40, 141 Kind_SimpleSectSep = 41, 142 Kind_LinkedWord = 42, 143 Kind_ParamSect = 43, 144 Kind_ParamList = 44, 145 Kind_InternalRef = 45, 146 Kind_Copy = 46, 147 Kind_Text = 47, 148 Kind_MscFile = 48, 149 Kind_HtmlBlockQuote = 49, 150 Kind_VhdlFlow = 50, 151 Kind_ParBlock = 51, 152 Kind_DiaFile = 52, 153 Kind_Emoji = 53, 154 Kind_Sep = 54 155 }; 156 /*! Creates a new node */ DocNode(DocParser & parser)157 DocNode(DocParser &parser) : m_parser(parser) {} 158 159 /*! Destroys a node. */ ~DocNode()160 virtual ~DocNode() {} 161 162 /*! Returns the kind of node. Provides runtime type information */ 163 virtual Kind kind() const = 0; 164 165 /*! Returns the parent of this node or 0 for the root node. */ parent()166 DocNode *parent() const { return m_parent; } 167 168 /*! Sets a new parent for this node. */ setParent(DocNode * parent)169 void setParent(DocNode *parent) { m_parent = parent; } 170 171 /*! Acceptor function for node visitors. Part of the visitor pattern. 172 * @param v Abstract visitor. 173 */ 174 virtual void accept(DocVisitor *v) = 0; 175 176 /*! Returns TRUE iff this node is inside a preformatted section */ isPreformatted()177 bool isPreformatted() const { return m_insidePre; } 178 179 protected: 180 /*! Sets whether or not this item is inside a preformatted section */ setInsidePreformatted(bool p)181 void setInsidePreformatted(bool p) { m_insidePre = p; } 182 DocNode *m_parent = 0; 183 enum RefType { Unknown, Anchor, Section, Table }; 184 DocParser &m_parser; 185 private: 186 187 bool m_insidePre = false; 188 }; 189 190 using DocNodeList = std::vector< std::unique_ptr<DocNode> >; 191 192 /** Default accept implementation for compound nodes in the abstract 193 * syntax tree. 194 */ 195 template<class T> 196 class CompAccept : public DocNode 197 { 198 public: CompAccept(DocParser & parser)199 CompAccept(DocParser &parser) : DocNode(parser) {} accept(DocVisitor * v)200 void accept(DocVisitor *v) override 201 { 202 T *obj = dynamic_cast<T *>(this); 203 v->visitPre(obj); 204 for (const auto &n : m_children) n->accept(v); 205 v->visitPost(obj); 206 } children()207 const DocNodeList &children() const { return m_children; } children()208 DocNodeList &children() { return m_children; } 209 210 protected: 211 DocNodeList m_children; 212 }; 213 214 215 /** Node representing a word 216 */ 217 class DocWord : public DocNode 218 { 219 public: 220 DocWord(DocParser &parser,DocNode *parent,const QCString &word); word()221 QCString word() const { return m_word; } kind()222 Kind kind() const override { return Kind_Word; } accept(DocVisitor * v)223 void accept(DocVisitor *v) override { v->visit(this); } 224 225 private: 226 QCString m_word; 227 }; 228 229 /** Node representing a word that can be linked to something 230 */ 231 class DocLinkedWord : public DocNode 232 { 233 public: 234 DocLinkedWord(DocParser &parser,DocNode *parent,const QCString &word, 235 const QCString &ref,const QCString &file, 236 const QCString &anchor,const QCString &tooltip); word()237 QCString word() const { return m_word; } kind()238 Kind kind() const override { return Kind_LinkedWord; } file()239 QCString file() const { return m_file; } relPath()240 QCString relPath() const { return m_relPath; } ref()241 QCString ref() const { return m_ref; } anchor()242 QCString anchor() const { return m_anchor; } tooltip()243 QCString tooltip() const { return m_tooltip; } accept(DocVisitor * v)244 void accept(DocVisitor *v) override { v->visit(this); } 245 246 private: 247 QCString m_word; 248 QCString m_ref; 249 QCString m_file; 250 QCString m_relPath; 251 QCString m_anchor; 252 QCString m_tooltip; 253 }; 254 255 /** Node representing a URL (or email address) */ 256 class DocURL : public DocNode 257 { 258 public: DocURL(DocParser & parser,DocNode * parent,const QCString & url,bool isEmail)259 DocURL(DocParser &parser,DocNode *parent,const QCString &url,bool isEmail) : 260 DocNode(parser), m_url(url), m_isEmail(isEmail) { m_parent=parent; } url()261 QCString url() const { return m_url; } kind()262 Kind kind() const override { return Kind_URL; } accept(DocVisitor * v)263 void accept(DocVisitor *v) override { v->visit(this); } isEmail()264 bool isEmail() const { return m_isEmail; } 265 266 private: 267 QCString m_url; 268 bool m_isEmail = false; 269 }; 270 271 /** Node representing a line break */ 272 class DocLineBreak : public DocNode 273 { 274 public: DocLineBreak(DocParser & parser,DocNode * parent)275 DocLineBreak(DocParser &parser,DocNode *parent) : DocNode(parser) { m_parent = parent; } DocLineBreak(DocParser & parser,DocNode * parent,const HtmlAttribList & attribs)276 DocLineBreak(DocParser &parser,DocNode *parent,const HtmlAttribList &attribs) 277 : DocNode(parser), m_attribs(attribs) { m_parent = parent; } kind()278 Kind kind() const override { return Kind_LineBreak; } accept(DocVisitor * v)279 void accept(DocVisitor *v) override { v->visit(this); } 280 attribs()281 const HtmlAttribList &attribs() const { return m_attribs; } 282 283 private: 284 HtmlAttribList m_attribs; 285 }; 286 287 /** Node representing a horizontal ruler */ 288 class DocHorRuler : public DocNode 289 { 290 public: DocHorRuler(DocParser & parser,DocNode * parent,const HtmlAttribList & attribs)291 DocHorRuler(DocParser &parser,DocNode *parent,const HtmlAttribList &attribs) 292 : DocNode(parser), m_attribs(attribs) { m_parent = parent; } kind()293 Kind kind() const override { return Kind_HorRuler; } accept(DocVisitor * v)294 void accept(DocVisitor *v) override { v->visit(this); } 295 attribs()296 const HtmlAttribList &attribs() const { return m_attribs; } 297 298 private: 299 HtmlAttribList m_attribs; 300 }; 301 302 /** Node representing an anchor */ 303 class DocAnchor : public DocNode 304 { 305 public: 306 DocAnchor(DocParser &parser,DocNode *parent,const QCString &id,bool newAnchor); kind()307 Kind kind() const override { return Kind_Anchor; } anchor()308 QCString anchor() const { return m_anchor; } file()309 QCString file() const { return m_file; } accept(DocVisitor * v)310 void accept(DocVisitor *v) override { v->visit(this); } 311 attribs()312 const HtmlAttribList &attribs() const { return m_attribs; } 313 314 private: 315 QCString m_anchor; 316 QCString m_file; 317 HtmlAttribList m_attribs; 318 }; 319 320 /** Node representing a citation of some bibliographic reference */ 321 class DocCite : public DocNode 322 { 323 public: 324 DocCite(DocParser &parser,DocNode *parent,const QCString &target,const QCString &context); kind()325 Kind kind() const override { return Kind_Ref; } file()326 QCString file() const { return m_file; } relPath()327 QCString relPath() const { return m_relPath; } ref()328 QCString ref() const { return m_ref; } anchor()329 QCString anchor() const { return m_anchor; } text()330 QCString text() const { return m_text; } accept(DocVisitor * v)331 void accept(DocVisitor *v) override { v->visit(this); } 332 333 private: 334 QCString m_file; 335 QCString m_relPath; 336 QCString m_ref; 337 QCString m_anchor; 338 QCString m_text; 339 }; 340 341 342 /** Node representing a style change */ 343 class DocStyleChange : public DocNode 344 { 345 public: 346 enum Style { Bold = (1<<0), 347 Italic = (1<<1), 348 Code = (1<<2), 349 Center = (1<<3), 350 Small = (1<<4), 351 Subscript = (1<<5), 352 Superscript = (1<<6), 353 Preformatted = (1<<7), 354 Span = (1<<8), 355 Div = (1<<9), 356 Strike = (1<<10), 357 Underline = (1<<11), 358 Del = (1<<12), 359 Ins = (1<<13), 360 S = (1<<14), 361 Details = (1<<15), 362 Summary = (1<<16), 363 Cite = (1<<17) 364 }; 365 366 DocStyleChange(DocParser &parser,DocNode *parent,uint position,Style s,const QCString &tagName,bool enable, 367 const HtmlAttribList *attribs=0) : DocNode(parser)368 DocNode(parser), m_position(position), m_style(s), m_enable(enable) 369 { m_parent = parent; if (attribs) m_attribs=*attribs; m_tagName = tagName.lower();} kind()370 Kind kind() const override { return Kind_StyleChange; } style()371 Style style() const { return m_style; } 372 const char *styleString() const; enable()373 bool enable() const { return m_enable; } position()374 uint position() const { return m_position; } accept(DocVisitor * v)375 void accept(DocVisitor *v) override { v->visit(this); } attribs()376 const HtmlAttribList &attribs() const { return m_attribs; } tagName()377 QCString tagName() const { return m_tagName; } 378 379 private: 380 uint m_position = 0; 381 Style m_style = Bold; 382 bool m_enable = false; 383 HtmlAttribList m_attribs; 384 QCString m_tagName; 385 }; 386 387 /** Node representing a special symbol */ 388 class DocSymbol : public DocNode 389 { 390 public: 391 enum SymType { Sym_Unknown = -1, 392 Sym_nbsp, Sym_iexcl, Sym_cent, Sym_pound, Sym_curren, 393 Sym_yen, Sym_brvbar, Sym_sect, Sym_uml, Sym_copy, 394 Sym_ordf, Sym_laquo, Sym_not, Sym_shy, Sym_reg, 395 Sym_macr, Sym_deg, Sym_plusmn, Sym_sup2, Sym_sup3, 396 Sym_acute, Sym_micro, Sym_para, Sym_middot, Sym_cedil, 397 Sym_sup1, Sym_ordm, Sym_raquo, Sym_frac14, Sym_frac12, 398 Sym_frac34, Sym_iquest, Sym_Agrave, Sym_Aacute, Sym_Acirc, 399 Sym_Atilde, Sym_Auml, Sym_Aring, Sym_AElig, Sym_Ccedil, 400 Sym_Egrave, Sym_Eacute, Sym_Ecirc, Sym_Euml, Sym_Igrave, 401 Sym_Iacute, Sym_Icirc, Sym_Iuml, Sym_ETH, Sym_Ntilde, 402 Sym_Ograve, Sym_Oacute, Sym_Ocirc, Sym_Otilde, Sym_Ouml, 403 Sym_times, Sym_Oslash, Sym_Ugrave, Sym_Uacute, Sym_Ucirc, 404 Sym_Uuml, Sym_Yacute, Sym_THORN, Sym_szlig, Sym_agrave, 405 Sym_aacute, Sym_acirc, Sym_atilde, Sym_auml, Sym_aring, 406 Sym_aelig, Sym_ccedil, Sym_egrave, Sym_eacute, Sym_ecirc, 407 Sym_euml, Sym_igrave, Sym_iacute, Sym_icirc, Sym_iuml, 408 Sym_eth, Sym_ntilde, Sym_ograve, Sym_oacute, Sym_ocirc, 409 Sym_otilde, Sym_ouml, Sym_divide, Sym_oslash, Sym_ugrave, 410 Sym_uacute, Sym_ucirc, Sym_uuml, Sym_yacute, Sym_thorn, 411 Sym_yuml, Sym_fnof, Sym_Alpha, Sym_Beta, Sym_Gamma, 412 Sym_Delta, Sym_Epsilon, Sym_Zeta, Sym_Eta, Sym_Theta, 413 Sym_Iota, Sym_Kappa, Sym_Lambda, Sym_Mu, Sym_Nu, 414 Sym_Xi, Sym_Omicron, Sym_Pi, Sym_Rho, Sym_Sigma, 415 Sym_Tau, Sym_Upsilon, Sym_Phi, Sym_Chi, Sym_Psi, 416 Sym_Omega, Sym_alpha, Sym_beta, Sym_gamma, Sym_delta, 417 Sym_epsilon, Sym_zeta, Sym_eta, Sym_theta, Sym_iota, 418 Sym_kappa, Sym_lambda, Sym_mu, Sym_nu, Sym_xi, 419 Sym_omicron, Sym_pi, Sym_rho, Sym_sigmaf, Sym_sigma, 420 Sym_tau, Sym_upsilon, Sym_phi, Sym_chi, Sym_psi, 421 Sym_omega, Sym_thetasym, Sym_upsih, Sym_piv, Sym_bull, 422 Sym_hellip, Sym_prime, Sym_Prime, Sym_oline, Sym_frasl, 423 Sym_weierp, Sym_image, Sym_real, Sym_trade, Sym_alefsym, 424 Sym_larr, Sym_uarr, Sym_rarr, Sym_darr, Sym_harr, 425 Sym_crarr, Sym_lArr, Sym_uArr, Sym_rArr, Sym_dArr, 426 Sym_hArr, Sym_forall, Sym_part, Sym_exist, Sym_empty, 427 Sym_nabla, Sym_isin, Sym_notin, Sym_ni, Sym_prod, 428 Sym_sum, Sym_minus, Sym_lowast, Sym_radic, Sym_prop, 429 Sym_infin, Sym_ang, Sym_and, Sym_or, Sym_cap, 430 Sym_cup, Sym_int, Sym_there4, Sym_sim, Sym_cong, 431 Sym_asymp, Sym_ne, Sym_equiv, Sym_le, Sym_ge, 432 Sym_sub, Sym_sup, Sym_nsub, Sym_sube, Sym_supe, 433 Sym_oplus, Sym_otimes, Sym_perp, Sym_sdot, Sym_lceil, 434 Sym_rceil, Sym_lfloor, Sym_rfloor, Sym_lang, Sym_rang, 435 Sym_loz, Sym_spades, Sym_clubs, Sym_hearts, Sym_diams, 436 Sym_quot, Sym_amp, Sym_lt, Sym_gt, Sym_OElig, 437 Sym_oelig, Sym_Scaron, Sym_scaron, Sym_Yuml, Sym_circ, 438 Sym_tilde, Sym_ensp, Sym_emsp, Sym_thinsp, Sym_zwnj, 439 Sym_zwj, Sym_lrm, Sym_rlm, Sym_ndash, Sym_mdash, 440 Sym_lsquo, Sym_rsquo, Sym_sbquo, Sym_ldquo, Sym_rdquo, 441 Sym_bdquo, Sym_dagger, Sym_Dagger, Sym_permil, Sym_lsaquo, 442 Sym_rsaquo, Sym_euro, 443 444 /* doxygen extensions */ 445 Sym_tm, Sym_apos, 446 447 /* doxygen commands mapped */ 448 Sym_BSlash, Sym_At, Sym_Less, Sym_Greater, Sym_Amp, 449 Sym_Dollar, Sym_Hash, Sym_DoubleColon, Sym_Percent, Sym_Pipe, 450 Sym_Quot, Sym_Minus, Sym_Plus, Sym_Dot, Sym_Colon, Sym_Equal 451 }; 452 enum PerlType { Perl_unknown = 0, Perl_string, Perl_char, Perl_symbol, Perl_umlaut, 453 Perl_acute, Perl_grave, Perl_circ, Perl_slash, Perl_tilde, 454 Perl_cedilla, Perl_ring 455 }; 456 typedef struct PerlSymb { 457 const char *symb; 458 const PerlType type; 459 }PerlSymb; DocSymbol(DocParser & parser,DocNode * parent,SymType s)460 DocSymbol(DocParser &parser,DocNode *parent,SymType s) : 461 DocNode(parser), m_symbol(s) { m_parent = parent; } symbol()462 SymType symbol() const { return m_symbol; } kind()463 Kind kind() const override { return Kind_Symbol; } accept(DocVisitor * v)464 void accept(DocVisitor *v) override { v->visit(this); } 465 static SymType decodeSymbol(const QCString &symName); 466 467 private: 468 SymType m_symbol = Sym_Unknown; 469 }; 470 471 /** Node representing a n emoji */ 472 class DocEmoji : public DocNode 473 { 474 public: 475 DocEmoji(DocParser &parser,DocNode *parent,const QCString &symName); name()476 QCString name() const { return m_symName; } index()477 int index() const { return m_index; } kind()478 Kind kind() const override { return Kind_Emoji; } accept(DocVisitor * v)479 void accept(DocVisitor *v) override { v->visit(this); } 480 481 private: 482 QCString m_symName; 483 int m_index = 0; 484 }; 485 486 /** Node representing some amount of white space */ 487 class DocWhiteSpace : public DocNode 488 { 489 public: DocWhiteSpace(DocParser & parser,DocNode * parent,const QCString & chars)490 DocWhiteSpace(DocParser &parser,DocNode *parent,const QCString &chars) : 491 DocNode(parser), m_chars(chars) { m_parent = parent; } kind()492 Kind kind() const override { return Kind_WhiteSpace; } chars()493 QCString chars() const { return m_chars; } accept(DocVisitor * v)494 void accept(DocVisitor *v) override { v->visit(this); } 495 private: 496 QCString m_chars; 497 }; 498 499 /** Node representing a separator */ 500 class DocSeparator : public DocNode 501 { 502 public: DocSeparator(DocParser & parser,DocNode * parent,const QCString & chars)503 DocSeparator(DocParser &parser,DocNode *parent,const QCString &chars) : 504 DocNode(parser), m_chars(chars) { m_parent = parent; } kind()505 Kind kind() const override { return Kind_Sep; } chars()506 QCString chars() const { return m_chars; } accept(DocVisitor *)507 void accept(DocVisitor *) override { } 508 private: 509 QCString m_chars; 510 }; 511 512 /** Node representing a verbatim, unparsed text fragment */ 513 class DocVerbatim : public DocNode 514 { 515 public: 516 enum Type { Code, HtmlOnly, ManOnly, LatexOnly, RtfOnly, XmlOnly, Verbatim, Dot, Msc, DocbookOnly, PlantUML, JavaDocCode, JavaDocLiteral }; 517 DocVerbatim(DocParser &parser,DocNode *parent,const QCString &context, 518 const QCString &text, Type t,bool isExample, 519 const QCString &exampleFile,bool isBlock=FALSE,const QCString &lang=QCString()); kind()520 Kind kind() const override { return Kind_Verbatim; } type()521 Type type() const { return m_type; } text()522 QCString text() const { return m_text; } context()523 QCString context() const { return m_context; } accept(DocVisitor * v)524 void accept(DocVisitor *v) override { v->visit(this); } isExample()525 bool isExample() const { return m_isExample; } exampleFile()526 QCString exampleFile() const { return m_exampleFile; } relPath()527 QCString relPath() const { return m_relPath; } language()528 QCString language() const { return m_lang; } isBlock()529 bool isBlock() const { return m_isBlock; } hasCaption()530 bool hasCaption() const { return !m_children.empty(); } width()531 QCString width() const { return m_width; } height()532 QCString height() const { return m_height; } engine()533 QCString engine() const { return m_engine; } useBitmap()534 bool useBitmap() const { return m_useBitmap; } children()535 const DocNodeList &children() const { return m_children; } children()536 DocNodeList &children() { return m_children; } srcFile()537 QCString srcFile() const { return m_srcFile; } srcLine()538 int srcLine() const { return m_srcLine; } setText(const QCString & t)539 void setText(const QCString &t) { m_text=t; } setWidth(const QCString & w)540 void setWidth(const QCString &w) { m_width=w; } setHeight(const QCString & h)541 void setHeight(const QCString &h) { m_height=h; } setEngine(const QCString & e)542 void setEngine(const QCString &e) { m_engine=e; } setUseBitmap(const bool & u)543 void setUseBitmap(const bool &u) { m_useBitmap=u; } setLocation(const QCString & file,int line)544 void setLocation(const QCString &file,int line) { m_srcFile=file; m_srcLine=line; } 545 546 private: 547 QCString m_context; 548 QCString m_text; 549 Type m_type = Code; 550 bool m_isExample = false; 551 QCString m_exampleFile; 552 QCString m_relPath; 553 QCString m_lang; 554 bool m_isBlock = false; 555 QCString m_width; 556 QCString m_height; 557 QCString m_engine; 558 bool m_useBitmap=false; // some PlantUML engines cannot output data in EPS format so bitmap format is required 559 DocNodeList m_children; 560 QCString m_srcFile; 561 int m_srcLine = -1; 562 }; 563 564 565 /** Node representing an included text block from file */ 566 class DocInclude : public DocNode 567 { 568 public: 569 enum Type { Include, DontInclude, VerbInclude, HtmlInclude, LatexInclude, 570 IncWithLines, Snippet , IncludeDoc, SnippetDoc, SnipWithLines, 571 DontIncWithLines, RtfInclude, ManInclude, DocbookInclude, XmlInclude}; DocInclude(DocParser & parser,DocNode * parent,const QCString & file,const QCString & context,Type t,bool isExample,const QCString & exampleFile,const QCString & blockId,bool isBlock)572 DocInclude(DocParser &parser,DocNode *parent,const QCString &file, 573 const QCString &context, Type t, 574 bool isExample,const QCString &exampleFile, 575 const QCString &blockId, bool isBlock) : 576 DocNode(parser), m_file(file), m_context(context), m_type(t), 577 m_isExample(isExample), m_isBlock(isBlock), 578 m_exampleFile(exampleFile), m_blockId(blockId) { m_parent = parent; } kind()579 Kind kind() const override { return Kind_Include; } file()580 QCString file() const { return m_file; } extension()581 QCString extension() const { int i=m_file.findRev('.'); 582 if (i!=-1) 583 return m_file.right(m_file.length()-(uint)i); 584 else 585 return QCString(); 586 } type()587 Type type() const { return m_type; } text()588 QCString text() const { return m_text; } context()589 QCString context() const { return m_context; } blockId()590 QCString blockId() const { return m_blockId; } isExample()591 bool isExample() const { return m_isExample; } exampleFile()592 QCString exampleFile() const { return m_exampleFile; } isBlock()593 bool isBlock() const { return m_isBlock; } accept(DocVisitor * v)594 void accept(DocVisitor *v) override { v->visit(this); } 595 void parse(); 596 597 private: 598 QCString m_file; 599 QCString m_context; 600 QCString m_text; 601 Type m_type; 602 bool m_isExample; 603 bool m_isBlock; 604 QCString m_exampleFile; 605 QCString m_blockId; 606 }; 607 608 /** Node representing a include/dontinclude operator block */ 609 class DocIncOperator : public DocNode 610 { 611 public: 612 enum Type { Line, SkipLine, Skip, Until }; DocIncOperator(DocParser & parser,DocNode * parent,Type t,const QCString & pat,const QCString & context,bool isExample,const QCString & exampleFile)613 DocIncOperator(DocParser &parser,DocNode *parent,Type t,const QCString &pat, 614 const QCString &context,bool isExample,const QCString &exampleFile) : 615 DocNode(parser), m_type(t), m_pattern(pat), m_context(context), 616 m_isFirst(FALSE), m_isLast(FALSE), 617 m_isExample(isExample), m_exampleFile(exampleFile) { m_parent = parent; } kind()618 Kind kind() const override { return Kind_IncOperator; } type()619 Type type() const { return m_type; } typeAsString()620 const char *typeAsString() const 621 { 622 switch(m_type) 623 { 624 case Line: return "line"; 625 case SkipLine: return "skipline"; 626 case Skip: return "skip"; 627 case Until: return "until"; 628 } 629 return ""; 630 } line()631 int line() const { return m_line; } showLineNo()632 bool showLineNo() const { return m_showLineNo; } text()633 QCString text() const { return m_text; } pattern()634 QCString pattern() const { return m_pattern; } context()635 QCString context() const { return m_context; } accept(DocVisitor * v)636 void accept(DocVisitor *v) override { v->visit(this); } isFirst()637 bool isFirst() const { return m_isFirst; } isLast()638 bool isLast() const { return m_isLast; } 639 void markFirst(bool v=TRUE) { m_isFirst = v; } 640 void markLast(bool v=TRUE) { m_isLast = v; } isExample()641 bool isExample() const { return m_isExample; } exampleFile()642 QCString exampleFile() const { return m_exampleFile; } includeFileName()643 QCString includeFileName() const { return m_includeFileName; } 644 void parse(); 645 646 private: 647 Type m_type = Line; 648 int m_line = 0; 649 bool m_showLineNo = false; 650 QCString m_text; 651 QCString m_pattern; 652 QCString m_context; 653 bool m_isFirst = false; 654 bool m_isLast = false; 655 bool m_isExample = false; 656 QCString m_exampleFile; 657 QCString m_includeFileName; 658 }; 659 660 /** Node representing an item of a cross-referenced list */ 661 class DocFormula : public DocNode 662 { 663 public: 664 DocFormula(DocParser &parser,DocNode *parent,int id); kind()665 Kind kind() const override { return Kind_Formula; } name()666 QCString name() const { return m_name; } text()667 QCString text() const { return m_text; } relPath()668 QCString relPath() const { return m_relPath; } id()669 int id() const { return m_id; } accept(DocVisitor * v)670 void accept(DocVisitor *v) override { v->visit(this); } isInline()671 bool isInline() { 672 if (m_text.length()>1 && m_text.at(0)=='\\' && m_text.at(1)=='[') return false; 673 if (m_text.length()>7 && m_text.startsWith("\\begin{")) return false; 674 return true; 675 } 676 677 private: 678 QCString m_name; 679 QCString m_text; 680 QCString m_relPath; 681 int m_id = 0; 682 }; 683 684 /** Node representing an entry in the index. */ 685 class DocIndexEntry : public DocNode 686 { 687 public: DocIndexEntry(DocParser & parser,DocNode * parent,const Definition * scope,const MemberDef * md)688 DocIndexEntry(DocParser &parser,DocNode *parent,const Definition *scope,const MemberDef *md) 689 : DocNode(parser), m_scope(scope), m_member(md){ m_parent = parent; } kind()690 Kind kind() const override { return Kind_IndexEntry; } 691 int parse(); scope()692 const Definition *scope() const { return m_scope; } member()693 const MemberDef *member() const { return m_member; } entry()694 QCString entry() const { return m_entry; } accept(DocVisitor * v)695 void accept(DocVisitor *v) override { v->visit(this); } 696 697 private: 698 QCString m_entry; 699 const Definition *m_scope = 0; 700 const MemberDef *m_member = 0; 701 }; 702 703 //----------------------------------------------------------------------- 704 705 /** Node representing an auto List */ 706 class DocAutoList : public CompAccept<DocAutoList> 707 { 708 public: 709 DocAutoList(DocParser &parser,DocNode *parent,int indent,bool isEnumList,int depth); kind()710 Kind kind() const override { return Kind_AutoList; } isEnumList()711 bool isEnumList() const { return m_isEnumList; } indent()712 int indent() const { return m_indent; } depth()713 int depth() const { return m_depth; } 714 int parse(); 715 716 private: 717 int m_indent = 0; 718 bool m_isEnumList = false; 719 int m_depth = 0; 720 }; 721 722 /** Node representing an item of a auto list */ 723 class DocAutoListItem : public CompAccept<DocAutoListItem> 724 { 725 public: 726 DocAutoListItem(DocParser &parser,DocNode *parent,int indent,int num); kind()727 Kind kind() const override { return Kind_AutoListItem; } itemNumber()728 int itemNumber() const { return m_itemNum; } 729 int parse(); 730 731 private: 732 int m_indent = 0; 733 int m_itemNum = 0; 734 }; 735 736 737 738 /** Node representing a simple section title */ 739 class DocTitle : public CompAccept<DocTitle> 740 { 741 public: DocTitle(DocParser & parser,DocNode * parent)742 DocTitle(DocParser &parser,DocNode *parent) : CompAccept<DocTitle>(parser) { m_parent = parent; } 743 void parse(); 744 void parseFromString(const QCString &title); kind()745 Kind kind() const override { return Kind_Title; } hasTitle()746 bool hasTitle() const { return !m_children.empty(); } 747 748 private: 749 }; 750 751 /** Node representing an item of a cross-referenced list */ 752 class DocXRefItem : public CompAccept<DocXRefItem> 753 { 754 public: 755 DocXRefItem(DocParser &parser,DocNode *parent,int id,const QCString &key); kind()756 Kind kind() const override { return Kind_XRefItem; } file()757 QCString file() const { return m_file; } anchor()758 QCString anchor() const { return m_anchor; } title()759 QCString title() const { return m_title; } relPath()760 QCString relPath() const { return m_relPath; } key()761 QCString key() const { return m_key; } 762 bool parse(); 763 764 private: 765 int m_id = 0; 766 QCString m_key; 767 QCString m_file; 768 QCString m_anchor; 769 QCString m_title; 770 QCString m_relPath; 771 }; 772 773 /** Node representing an image */ 774 class DocImage : public CompAccept<DocImage> 775 { 776 public: 777 enum Type { Html, Latex, Rtf, DocBook, Xml }; 778 DocImage(DocParser &parser,DocNode *parent,const HtmlAttribList &attribs, 779 const QCString &name,Type t,const QCString &url=QCString(), bool inlineImage = TRUE); kind()780 Kind kind() const override { return Kind_Image; } type()781 Type type() const { return m_type; } name()782 QCString name() const { return m_name; } hasCaption()783 bool hasCaption() const { return !m_children.empty(); } width()784 QCString width() const { return m_width; } height()785 QCString height() const { return m_height; } relPath()786 QCString relPath() const { return m_relPath; } url()787 QCString url() const { return m_url; } isInlineImage()788 bool isInlineImage() const { return m_inlineImage; } 789 bool isSVG() const; attribs()790 const HtmlAttribList &attribs() const { return m_attribs; } 791 void parse(); 792 793 private: 794 HtmlAttribList m_attribs; 795 QCString m_name; 796 Type m_type = Html; 797 QCString m_width; 798 QCString m_height; 799 QCString m_relPath; 800 QCString m_url; 801 bool m_inlineImage = false; 802 }; 803 804 template<class T> 805 class DocDiagramFileBase : public CompAccept<T> 806 { 807 public: DocDiagramFileBase(DocParser & parser,const QCString & name,const QCString & context,const QCString & srcFile,int srcLine)808 DocDiagramFileBase(DocParser &parser, const QCString &name,const QCString &context, 809 const QCString &srcFile,int srcLine) 810 : CompAccept<T>(parser), m_name(name), m_context(context), m_srcFile(srcFile), m_srcLine(srcLine) {} name()811 QCString name() const { return m_name; } file()812 QCString file() const { return m_file; } relPath()813 QCString relPath() const { return m_relPath; } hasCaption()814 bool hasCaption() const { return !this->m_children.empty(); } width()815 QCString width() const { return m_width; } height()816 QCString height() const { return m_height; } context()817 QCString context() const { return m_context; } srcFile()818 QCString srcFile() const { return m_srcFile; } srcLine()819 int srcLine() const { return m_srcLine; } 820 821 protected: 822 QCString m_name; 823 QCString m_file; 824 QCString m_relPath; 825 QCString m_width; 826 QCString m_height; 827 QCString m_context; 828 QCString m_srcFile; 829 int m_srcLine = -1; 830 }; 831 832 /** Node representing a dot file */ 833 class DocDotFile : public DocDiagramFileBase<DocDotFile> 834 { 835 public: 836 DocDotFile(DocParser &parser,DocNode *parent,const QCString &name,const QCString &context, 837 const QCString &srcFile,int srcLine); kind()838 Kind kind() const override { return Kind_DotFile; } 839 bool parse(); 840 }; 841 842 /** Node representing a msc file */ 843 class DocMscFile : public DocDiagramFileBase<DocMscFile> 844 { 845 public: 846 DocMscFile(DocParser &parser,DocNode *parent,const QCString &name,const QCString &context, 847 const QCString &srcFile,int srcLine); kind()848 Kind kind() const override { return Kind_MscFile; } 849 bool parse(); 850 }; 851 852 /** Node representing a dia file */ 853 class DocDiaFile : public DocDiagramFileBase<DocDiaFile> 854 { 855 public: 856 DocDiaFile(DocParser &parser,DocNode *parent,const QCString &name,const QCString &context, 857 const QCString &srcFile,int srcLine); kind()858 Kind kind() const override { return Kind_DiaFile; } 859 bool parse(); 860 }; 861 862 /** Node representing a VHDL flow chart */ 863 class DocVhdlFlow : public CompAccept<DocVhdlFlow> 864 { 865 public: 866 DocVhdlFlow(DocParser &parser,DocNode *parent); 867 void parse(); kind()868 Kind kind() const override { return Kind_VhdlFlow; } hasCaption()869 bool hasCaption() { return !m_children.empty(); } 870 private: 871 }; 872 873 /** Node representing a link to some item */ 874 class DocLink : public CompAccept<DocLink> 875 { 876 public: 877 DocLink(DocParser &parser,DocNode *parent,const QCString &target); 878 QCString parse(bool,bool isXmlLink=FALSE); kind()879 Kind kind() const override { return Kind_Link; } file()880 QCString file() const { return m_file; } relPath()881 QCString relPath() const { return m_relPath; } ref()882 QCString ref() const { return m_ref; } anchor()883 QCString anchor() const { return m_anchor; } 884 885 private: 886 QCString m_file; 887 QCString m_relPath; 888 QCString m_ref; 889 QCString m_anchor; 890 QCString m_refText; 891 }; 892 893 /** Node representing a reference to some item */ 894 class DocRef : public CompAccept<DocRef> 895 { 896 public: 897 DocRef(DocParser &parser,DocNode *parent,const QCString &target,const QCString &context); 898 void parse(); kind()899 Kind kind() const override { return Kind_Ref; } file()900 QCString file() const { return m_file; } relPath()901 QCString relPath() const { return m_relPath; } ref()902 QCString ref() const { return m_ref; } anchor()903 QCString anchor() const { return m_anchor; } targetTitle()904 QCString targetTitle() const { return m_text; } hasLinkText()905 bool hasLinkText() const { return !m_children.empty(); } refToAnchor()906 bool refToAnchor() const { return m_refType==Anchor; } refToSection()907 bool refToSection() const { return m_refType==Section; } refToTable()908 bool refToTable() const { return m_refType==Table; } isSubPage()909 bool isSubPage() const { return m_isSubPage; } 910 911 private: 912 RefType m_refType = Unknown; 913 bool m_isSubPage = false; 914 QCString m_file; 915 QCString m_relPath; 916 QCString m_ref; 917 QCString m_anchor; 918 QCString m_text; 919 }; 920 921 /** Node representing an internal reference to some item */ 922 class DocInternalRef : public CompAccept<DocInternalRef> 923 { 924 public: 925 DocInternalRef(DocParser &parser,DocNode *parent,const QCString &target); 926 void parse(); kind()927 Kind kind() const override { return Kind_Ref; } file()928 QCString file() const { return m_file; } relPath()929 QCString relPath() const { return m_relPath; } anchor()930 QCString anchor() const { return m_anchor; } 931 932 private: 933 QCString m_file; 934 QCString m_relPath; 935 QCString m_anchor; 936 }; 937 938 /** Node representing a Hypertext reference */ 939 class DocHRef : public CompAccept<DocHRef> 940 { 941 public: DocHRef(DocParser & parser,DocNode * parent,const HtmlAttribList & attribs,const QCString & url,const QCString & relPath,const QCString & file)942 DocHRef(DocParser &parser,DocNode *parent,const HtmlAttribList &attribs,const QCString &url, 943 const QCString &relPath, const QCString &file) : 944 CompAccept<DocHRef>(parser), m_attribs(attribs), m_url(url), m_relPath(relPath), m_file(file) { m_parent = parent; } 945 int parse(); url()946 QCString url() const { return m_url; } file()947 QCString file() const { return m_file; } relPath()948 QCString relPath() const { return m_relPath; } kind()949 Kind kind() const override { return Kind_HRef; } attribs()950 const HtmlAttribList &attribs() const { return m_attribs; } 951 952 private: 953 HtmlAttribList m_attribs; 954 QCString m_url; 955 QCString m_relPath; 956 QCString m_file; 957 }; 958 959 /** Node Html heading */ 960 class DocHtmlHeader : public CompAccept<DocHtmlHeader> 961 { 962 public: DocHtmlHeader(DocParser & parser,DocNode * parent,const HtmlAttribList & attribs,int level)963 DocHtmlHeader(DocParser &parser,DocNode *parent,const HtmlAttribList &attribs,int level) : 964 CompAccept<DocHtmlHeader>(parser), m_level(level), m_attribs(attribs) { m_parent = parent; } level()965 int level() const { return m_level; } kind()966 Kind kind() const override { return Kind_HtmlHeader; } attribs()967 const HtmlAttribList &attribs() const { return m_attribs; } 968 int parse(); 969 970 private: 971 int m_level = 0; 972 HtmlAttribList m_attribs; 973 }; 974 975 /** Node representing a Html description item */ 976 class DocHtmlDescTitle : public CompAccept<DocHtmlDescTitle> 977 { 978 public: DocHtmlDescTitle(DocParser & parser,DocNode * parent,const HtmlAttribList & attribs)979 DocHtmlDescTitle(DocParser &parser,DocNode *parent,const HtmlAttribList &attribs) : 980 CompAccept<DocHtmlDescTitle>(parser), m_attribs(attribs) { m_parent = parent; } kind()981 Kind kind() const override { return Kind_HtmlDescTitle; } attribs()982 const HtmlAttribList &attribs() const { return m_attribs; } 983 int parse(); 984 985 private: 986 HtmlAttribList m_attribs; 987 }; 988 989 /** Node representing a Html description list */ 990 class DocHtmlDescList : public CompAccept<DocHtmlDescList> 991 { 992 public: DocHtmlDescList(DocParser & parser,DocNode * parent,const HtmlAttribList & attribs)993 DocHtmlDescList(DocParser &parser,DocNode *parent,const HtmlAttribList &attribs) : 994 CompAccept<DocHtmlDescList>(parser), m_attribs(attribs) { m_parent = parent; } kind()995 Kind kind() const override { return Kind_HtmlDescList; } attribs()996 const HtmlAttribList &attribs() const { return m_attribs; } 997 int parse(); 998 999 private: 1000 HtmlAttribList m_attribs; 1001 }; 1002 1003 /** Node representing a normal section */ 1004 class DocSection : public CompAccept<DocSection> 1005 { 1006 public: DocSection(DocParser & parser,DocNode * parent,int level,const QCString & id)1007 DocSection(DocParser &parser,DocNode *parent,int level,const QCString &id) : 1008 CompAccept<DocSection>(parser), m_level(level), m_id(id) { m_parent = parent; } kind()1009 Kind kind() const override { return Kind_Section; } level()1010 int level() const { return m_level; } title()1011 QCString title() const { return m_title; } anchor()1012 QCString anchor() const { return m_anchor; } id()1013 QCString id() const { return m_id; } file()1014 QCString file() const { return m_file; } 1015 int parse(); 1016 1017 private: 1018 int m_level = 0; 1019 QCString m_id; 1020 QCString m_title; 1021 QCString m_anchor; 1022 QCString m_file; 1023 }; 1024 1025 /** Node representing a reference to a section */ 1026 class DocSecRefItem : public CompAccept<DocSecRefItem> 1027 { 1028 public: 1029 DocSecRefItem(DocParser &parser,DocNode *parent,const QCString &target); kind()1030 Kind kind() const override { return Kind_SecRefItem; } target()1031 QCString target() const { return m_target; } file()1032 QCString file() const { return m_file; } anchor()1033 QCString anchor() const { return m_anchor; } relPath()1034 QCString relPath() const { return m_relPath; } ref()1035 QCString ref() const { return m_ref; } refToTable()1036 bool refToTable() const { return m_refType==Table; } isSubPage()1037 bool isSubPage() const { return m_isSubPage; } 1038 void parse(); 1039 1040 private: 1041 QCString m_target; 1042 RefType m_refType = Unknown; 1043 bool m_isSubPage = false; 1044 QCString m_file; 1045 QCString m_relPath; 1046 QCString m_ref; 1047 QCString m_anchor; 1048 }; 1049 1050 /** Node representing a list of section references */ 1051 class DocSecRefList : public CompAccept<DocSecRefList> 1052 { 1053 public: DocSecRefList(DocParser & parser,DocNode * parent)1054 DocSecRefList(DocParser &parser,DocNode *parent) : CompAccept<DocSecRefList>(parser) { m_parent = parent; } 1055 void parse(); kind()1056 Kind kind() const override { return Kind_SecRefList; } 1057 1058 private: 1059 }; 1060 1061 /** Node representing an internal section of documentation */ 1062 class DocInternal : public CompAccept<DocInternal> 1063 { 1064 public: DocInternal(DocParser & parser,DocNode * parent)1065 DocInternal(DocParser &parser,DocNode *parent) : CompAccept<DocInternal>(parser) { m_parent = parent; } 1066 int parse(int); kind()1067 Kind kind() const override { return Kind_Internal; } 1068 1069 private: 1070 }; 1071 1072 /** Node representing an block of paragraphs */ 1073 class DocParBlock : public CompAccept<DocParBlock> 1074 { 1075 public: DocParBlock(DocParser & parser,DocNode * parent)1076 DocParBlock(DocParser &parser,DocNode *parent) : CompAccept<DocParBlock>(parser) { m_parent = parent; } 1077 int parse(); kind()1078 Kind kind() const override { return Kind_ParBlock; } 1079 1080 private: 1081 }; 1082 1083 1084 /** Node representing a simple list */ 1085 class DocSimpleList : public CompAccept<DocSimpleList> 1086 { 1087 public: DocSimpleList(DocParser & parser,DocNode * parent)1088 DocSimpleList(DocParser &parser,DocNode *parent) : CompAccept<DocSimpleList>(parser) { m_parent = parent; } kind()1089 Kind kind() const override { return Kind_SimpleList; } 1090 int parse(); 1091 1092 private: 1093 }; 1094 1095 /** Node representing a Html list */ 1096 class DocHtmlList : public CompAccept<DocHtmlList> 1097 { 1098 public: 1099 enum Type { Unordered, Ordered }; DocHtmlList(DocParser & parser,DocNode * parent,const HtmlAttribList & attribs,Type t)1100 DocHtmlList(DocParser &parser,DocNode *parent,const HtmlAttribList &attribs,Type t) : 1101 CompAccept<DocHtmlList>(parser), m_type(t), m_attribs(attribs) { m_parent = parent; } kind()1102 Kind kind() const override { return Kind_HtmlList; } type()1103 Type type() const { return m_type; } attribs()1104 const HtmlAttribList &attribs() const { return m_attribs; } 1105 int parse(); 1106 int parseXml(); 1107 1108 private: 1109 Type m_type = Unordered; 1110 HtmlAttribList m_attribs; 1111 }; 1112 1113 /** Node representing a simple section */ 1114 class DocSimpleSect : public CompAccept<DocSimpleSect> 1115 { 1116 public: 1117 enum Type 1118 { 1119 Unknown, See, Return, Author, Authors, Version, Since, Date, 1120 Note, Warning, Copyright, Pre, Post, Invar, Remark, Attention, User, Rcs 1121 }; 1122 DocSimpleSect(DocParser &parser,DocNode *parent,Type t); 1123 virtual ~DocSimpleSect(); kind()1124 Kind kind() const override { return Kind_SimpleSect; } type()1125 Type type() const { return m_type; } 1126 QCString typeString() const; 1127 void accept(DocVisitor *v) override; 1128 int parse(bool userTitle,bool needsSeparator); 1129 int parseRcs(); 1130 int parseXml(); 1131 void appendLinkWord(const QCString &word); hasTitle()1132 bool hasTitle() const { return m_title->hasTitle(); } 1133 1134 private: 1135 Type m_type = Unknown; 1136 DocTitle * m_title = 0; 1137 }; 1138 1139 /** Node representing a separator between two simple sections of the 1140 * same type. 1141 */ 1142 class DocSimpleSectSep : public DocNode 1143 { 1144 public: DocSimpleSectSep(DocParser & parser,DocNode * parent)1145 DocSimpleSectSep(DocParser &parser,DocNode *parent) : DocNode(parser) { m_parent = parent; } kind()1146 Kind kind() const override { return Kind_SimpleSectSep; } accept(DocVisitor * v)1147 void accept(DocVisitor *v) override { v->visit(this); } 1148 1149 private: 1150 }; 1151 1152 /** Node representing a parameter section */ 1153 class DocParamSect : public CompAccept<DocParamSect> 1154 { 1155 friend class DocParamList; 1156 public: 1157 enum Type 1158 { 1159 Unknown, Param, RetVal, Exception, TemplateParam 1160 }; 1161 enum Direction 1162 { 1163 In=1, Out=2, InOut=3, Unspecified=0 1164 }; DocParamSect(DocParser & parser,DocNode * parent,Type t)1165 DocParamSect(DocParser &parser,DocNode *parent,Type t) 1166 : CompAccept<DocParamSect>(parser), m_type(t), m_hasInOutSpecifier(FALSE), m_hasTypeSpecifier(FALSE) 1167 { m_parent = parent; } 1168 int parse(const QCString &cmdName,bool xmlContext,Direction d); kind()1169 Kind kind() const override { return Kind_ParamSect; } type()1170 Type type() const { return m_type; } hasInOutSpecifier()1171 bool hasInOutSpecifier() const { return m_hasInOutSpecifier; } hasTypeSpecifier()1172 bool hasTypeSpecifier() const { return m_hasTypeSpecifier; } 1173 1174 private: 1175 Type m_type = Unknown; 1176 bool m_hasInOutSpecifier = false; 1177 bool m_hasTypeSpecifier = false; 1178 }; 1179 1180 /** Node representing a paragraph in the documentation tree */ 1181 class DocPara : public CompAccept<DocPara> 1182 { 1183 public: DocPara(DocParser & parser,DocNode * parent)1184 DocPara(DocParser &parser,DocNode *parent) : 1185 CompAccept<DocPara>(parser), m_isFirst(FALSE), m_isLast(FALSE) { m_parent = parent; } 1186 int parse(); kind()1187 Kind kind() const override { return Kind_Para; } isEmpty()1188 bool isEmpty() const { return m_children.empty(); } 1189 void markFirst(bool v=TRUE) { m_isFirst=v; } 1190 void markLast(bool v=TRUE) { m_isLast=v; } isFirst()1191 bool isFirst() const { return m_isFirst; } isLast()1192 bool isLast() const { return m_isLast; } 1193 1194 int handleCommand(const QCString &cmdName,const int tok); 1195 int handleHtmlStartTag(const QCString &tagName,const HtmlAttribList &tagHtmlAttribs); 1196 int handleHtmlEndTag(const QCString &tagName); 1197 int handleSimpleSection(DocSimpleSect::Type t,bool xmlContext=FALSE); 1198 int handleXRefItem(); 1199 int handleParamSection(const QCString &cmdName,DocParamSect::Type t, 1200 bool xmlContext, 1201 int direction); 1202 void handleIncludeOperator(const QCString &cmdName,DocIncOperator::Type t); 1203 void handleImage(const QCString &cmdName); 1204 template<class T> void handleFile(const QCString &cmdName); 1205 void handleInclude(const QCString &cmdName,DocInclude::Type t); 1206 void handleLink(const QCString &cmdName,bool isJavaLink); 1207 void handleCite(); 1208 void handleEmoji(); 1209 void handleRef(const QCString &cmdName); 1210 void handleSection(const QCString &cmdName); 1211 void handleInheritDoc(); 1212 void handleVhdlFlow(); 1213 void handleIline(); 1214 int handleStartCode(); 1215 int handleHtmlHeader(const HtmlAttribList &tagHtmlAttribs,int level); 1216 1217 bool injectToken(int tok,const QCString &tokText); attribs()1218 const HtmlAttribList &attribs() const { return m_attribs; } setAttribs(const HtmlAttribList & attribs)1219 void setAttribs(const HtmlAttribList &attribs) { m_attribs = attribs; } 1220 1221 private: 1222 QCString m_sectionId; 1223 bool m_isFirst = false; 1224 bool m_isLast = false; 1225 HtmlAttribList m_attribs; 1226 }; 1227 1228 using DocParaList = std::vector< std::unique_ptr<DocPara> >; 1229 1230 /** Node representing a parameter list. */ 1231 class DocParamList : public DocNode 1232 { 1233 public: DocParamList(DocParser & parser,DocNode * parent,DocParamSect::Type t,DocParamSect::Direction d)1234 DocParamList(DocParser &parser,DocNode *parent,DocParamSect::Type t,DocParamSect::Direction d) 1235 : DocNode(parser), m_type(t), m_dir(d) 1236 { 1237 m_parent = parent; 1238 } ~DocParamList()1239 virtual ~DocParamList() { } kind()1240 Kind kind() const override { return Kind_ParamList; } parameters()1241 DocNodeList ¶meters() { return m_params; } paramTypes()1242 DocNodeList ¶mTypes() { return m_paramTypes; } type()1243 DocParamSect::Type type() const { return m_type; } direction()1244 DocParamSect::Direction direction() const { return m_dir; } 1245 void markFirst(bool b=TRUE) { m_isFirst=b; } 1246 void markLast(bool b=TRUE) { m_isLast=b; } isFirst()1247 bool isFirst() const { return m_isFirst; } isLast()1248 bool isLast() const { return m_isLast; } accept(DocVisitor * v)1249 void accept(DocVisitor *v) override 1250 { 1251 v->visitPre(this); 1252 for (const auto &n : m_paragraphs) n->accept(v); 1253 v->visitPost(this); 1254 } 1255 int parse(const QCString &cmdName); 1256 int parseXml(const QCString ¶mName); 1257 1258 private: 1259 DocParaList m_paragraphs; 1260 DocNodeList m_params; 1261 DocNodeList m_paramTypes; 1262 DocParamSect::Type m_type = DocParamSect::Unknown; 1263 DocParamSect::Direction m_dir = DocParamSect::Unspecified; 1264 bool m_isFirst = false; 1265 bool m_isLast = false; 1266 }; 1267 1268 /** Node representing a simple list item */ 1269 class DocSimpleListItem : public DocNode 1270 { 1271 public: DocSimpleListItem(DocParser & parser,DocNode * parent)1272 DocSimpleListItem(DocParser &parser,DocNode *parent) : 1273 DocNode(parser) { m_paragraph=new DocPara(parser,this); m_parent = parent; } 1274 int parse(); ~DocSimpleListItem()1275 virtual ~DocSimpleListItem() { delete m_paragraph; } kind()1276 Kind kind() const override { return Kind_SimpleListItem; } accept(DocVisitor * v)1277 void accept(DocVisitor *v) override 1278 { 1279 v->visitPre(this); 1280 m_paragraph->accept(v); 1281 v->visitPost(this); 1282 } 1283 1284 private: 1285 DocPara *m_paragraph = 0; 1286 }; 1287 1288 /** Node representing a HTML list item */ 1289 class DocHtmlListItem : public CompAccept<DocHtmlListItem> 1290 { 1291 public: DocHtmlListItem(DocParser & parser,DocNode * parent,const HtmlAttribList & attribs,int num)1292 DocHtmlListItem(DocParser &parser,DocNode *parent,const HtmlAttribList &attribs,int num) : 1293 CompAccept<DocHtmlListItem>(parser), m_attribs(attribs), m_itemNum(num) { m_parent = parent; } kind()1294 Kind kind() const override { return Kind_HtmlListItem; } itemNumber()1295 int itemNumber() const { return m_itemNum; } attribs()1296 const HtmlAttribList &attribs() const { return m_attribs; } 1297 int parse(); 1298 int parseXml(); 1299 1300 private: 1301 HtmlAttribList m_attribs; 1302 int m_itemNum = 0; 1303 }; 1304 1305 /** Node representing a HTML description data */ 1306 class DocHtmlDescData : public CompAccept<DocHtmlDescData> 1307 { 1308 public: DocHtmlDescData(DocParser & parser,DocNode * parent)1309 DocHtmlDescData(DocParser &parser,DocNode *parent) : CompAccept<DocHtmlDescData>(parser) { m_parent = parent; } kind()1310 Kind kind() const override { return Kind_HtmlDescData; } attribs()1311 const HtmlAttribList &attribs() const { return m_attribs; } 1312 int parse(); 1313 1314 private: 1315 HtmlAttribList m_attribs; 1316 }; 1317 1318 /** Node representing a HTML table cell */ 1319 class DocHtmlCell : public CompAccept<DocHtmlCell> 1320 { 1321 friend class DocHtmlTable; 1322 public: 1323 enum Alignment { Left, Right, Center }; 1324 enum Valignment {Top, Middle, Bottom}; DocHtmlCell(DocParser & parser,DocNode * parent,const HtmlAttribList & attribs,bool isHeading)1325 DocHtmlCell(DocParser &parser,DocNode *parent,const HtmlAttribList &attribs,bool isHeading) : 1326 CompAccept<DocHtmlCell>(parser), m_isHeading(isHeading), m_attribs(attribs) { m_parent = parent; } isHeading()1327 bool isHeading() const { return m_isHeading; } isFirst()1328 bool isFirst() const { return m_isFirst; } isLast()1329 bool isLast() const { return m_isLast; } kind()1330 Kind kind() const override { return Kind_HtmlCell; } 1331 void markFirst(bool v=TRUE) { m_isFirst=v; } 1332 void markLast(bool v=TRUE) { m_isLast=v; } attribs()1333 const HtmlAttribList &attribs() const { return m_attribs; } 1334 int parse(); 1335 int parseXml(); rowIndex()1336 uint rowIndex() const { return m_rowIdx; } columnIndex()1337 uint columnIndex() const { return m_colIdx; } 1338 uint rowSpan() const; 1339 uint colSpan() const; 1340 Alignment alignment() const; 1341 Valignment valignment() const; 1342 1343 private: setRowIndex(uint idx)1344 void setRowIndex(uint idx) { m_rowIdx = idx; } setColumnIndex(uint idx)1345 void setColumnIndex(uint idx) { m_colIdx = idx; } 1346 bool m_isHeading = false; 1347 bool m_isFirst = false; 1348 bool m_isLast = false; 1349 HtmlAttribList m_attribs; 1350 uint m_rowIdx = (uint)-1; 1351 uint m_colIdx = (uint)-1; 1352 }; 1353 1354 /** Node representing a HTML table caption */ 1355 class DocHtmlCaption : public CompAccept<DocHtmlCaption> 1356 { 1357 public: 1358 DocHtmlCaption(DocParser &parser,DocNode *parent,const HtmlAttribList &attribs); kind()1359 Kind kind() const override { return Kind_HtmlCaption; } attribs()1360 const HtmlAttribList &attribs() const { return m_attribs; } 1361 int parse(); hasCaptionId()1362 bool hasCaptionId() const { return m_hasCaptionId; } file()1363 QCString file() const { return m_file; } anchor()1364 QCString anchor() const { return m_anchor; } 1365 1366 private: 1367 HtmlAttribList m_attribs; 1368 bool m_hasCaptionId = false; 1369 QCString m_file; 1370 QCString m_anchor; 1371 }; 1372 1373 /** Node representing a HTML table row */ 1374 class DocHtmlRow : public CompAccept<DocHtmlRow> 1375 { 1376 friend class DocHtmlTable; 1377 public: DocHtmlRow(DocParser & parser,DocNode * parent,const HtmlAttribList & attribs)1378 DocHtmlRow(DocParser &parser,DocNode *parent,const HtmlAttribList &attribs) 1379 : CompAccept<DocHtmlRow>(parser), m_attribs(attribs) { m_parent = parent; } kind()1380 Kind kind() const override { return Kind_HtmlRow; } numCells()1381 size_t numCells() const { return m_children.size(); } attribs()1382 const HtmlAttribList &attribs() const { return m_attribs; } 1383 int parse(); 1384 int parseXml(bool header); isHeading()1385 bool isHeading() const { // a row is a table heading if all cells are marked as such 1386 bool heading=TRUE; 1387 for (const auto &n : m_children) 1388 { 1389 if (n->kind()==Kind_HtmlCell) 1390 { 1391 heading = heading && ((DocHtmlCell*)n.get())->isHeading(); 1392 } 1393 } 1394 return !m_children.empty() && heading; 1395 } setVisibleCells(uint n)1396 void setVisibleCells(uint n) { m_visibleCells = n; } visibleCells()1397 uint visibleCells() const { return m_visibleCells; } rowIndex()1398 uint rowIndex() const { return m_rowIdx; } 1399 1400 private: setRowIndex(uint idx)1401 void setRowIndex(uint idx) { m_rowIdx = idx; } 1402 HtmlAttribList m_attribs; 1403 uint m_visibleCells = 0; 1404 uint m_rowIdx = (uint)-1; 1405 }; 1406 1407 /** Node representing a HTML table */ 1408 class DocHtmlTable : public CompAccept<DocHtmlTable> 1409 { 1410 public: DocHtmlTable(DocParser & parser,DocNode * parent,const HtmlAttribList & attribs)1411 DocHtmlTable(DocParser &parser,DocNode *parent,const HtmlAttribList &attribs) 1412 : CompAccept<DocHtmlTable>(parser), m_attribs(attribs) { m_caption=0; m_numCols=0; m_parent = parent; } ~DocHtmlTable()1413 ~DocHtmlTable() { delete m_caption; } kind()1414 Kind kind() const override { return Kind_HtmlTable; } numRows()1415 size_t numRows() const { return m_children.size(); } hasCaption()1416 bool hasCaption() { return m_caption!=0; } attribs()1417 const HtmlAttribList &attribs() const { return m_attribs; } 1418 int parse(); 1419 int parseXml(); numColumns()1420 size_t numColumns() const { return m_numCols; } 1421 void accept(DocVisitor *v) override; caption()1422 DocHtmlCaption *caption() const { return m_caption; } firstRow()1423 DocHtmlRow *firstRow() const { 1424 return (!m_children.empty() && m_children.front()->kind()==Kind_HtmlRow) ? 1425 (DocHtmlRow*)m_children.front().get() : 0; 1426 } 1427 1428 private: 1429 void computeTableGrid(); 1430 DocHtmlCaption *m_caption = 0; 1431 HtmlAttribList m_attribs; 1432 size_t m_numCols = 0; 1433 }; 1434 1435 /** Node representing an HTML blockquote */ 1436 class DocHtmlBlockQuote : public CompAccept<DocHtmlBlockQuote> 1437 { 1438 public: DocHtmlBlockQuote(DocParser & parser,DocNode * parent,const HtmlAttribList & attribs)1439 DocHtmlBlockQuote(DocParser &parser,DocNode *parent,const HtmlAttribList &attribs) 1440 : CompAccept<DocHtmlBlockQuote>(parser), m_attribs(attribs) { m_parent = parent; } kind()1441 Kind kind() const override { return Kind_HtmlBlockQuote; } 1442 int parse(); attribs()1443 const HtmlAttribList &attribs() const { return m_attribs; } 1444 1445 private: 1446 HtmlAttribList m_attribs; 1447 }; 1448 1449 /** Root node of a text fragment */ 1450 class DocText : public CompAccept<DocText> 1451 { 1452 public: DocText(DocParser & parser)1453 DocText(DocParser &parser) : CompAccept<DocText>(parser) {} kind()1454 Kind kind() const override { return Kind_Text; } 1455 void parse(); isEmpty()1456 bool isEmpty() const { return m_children.empty(); } 1457 }; 1458 1459 /** Root node of documentation tree */ 1460 class DocRoot : public CompAccept<DocRoot> 1461 { 1462 public: DocRoot(DocParser & parser,bool indent,bool sl)1463 DocRoot(DocParser &parser,bool indent,bool sl) : CompAccept<DocRoot>(parser), m_indent(indent), m_singleLine(sl) {} kind()1464 Kind kind() const override { return Kind_Root; } 1465 void parse(); indent()1466 bool indent() const { return m_indent; } singleLine()1467 bool singleLine() const { return m_singleLine; } isEmpty()1468 bool isEmpty() const { return m_children.empty(); } 1469 1470 private: 1471 bool m_indent = false; 1472 bool m_singleLine = false; 1473 }; 1474 1475 1476 #endif 1477