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 &parameters()       { return m_params; }
paramTypes()1242     DocNodeList &paramTypes()       { 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 &paramName);
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