diff options
Diffstat (limited to 'src/docparser.cpp')
-rw-r--r-- | src/docparser.cpp | 725 |
1 files changed, 497 insertions, 228 deletions
diff --git a/src/docparser.cpp b/src/docparser.cpp index 25d4b0c..a5c0cc7 100644 --- a/src/docparser.cpp +++ b/src/docparser.cpp @@ -26,6 +26,7 @@ #include <qdict.h> #include <qregexp.h> #include <ctype.h> +#include <qcstringlist.h> #include "doxygen.h" #include "debug.h" @@ -54,6 +55,9 @@ #include "growbuf.h" #include "markdown.h" #include "htmlentity.h" +#include "emoji.h" + +#define TK_COMMAND_CHAR(token) ((token)==TK_COMMAND_AT ? '@' : '\\') // debug off #define DBG(x) do {} while(0) @@ -146,6 +150,9 @@ struct DocParserContext static QStack<DocParserContext> g_parserStack; //--------------------------------------------------------------------------- +static void handleImg(DocNode *parent,QList<DocNode> &children,const HtmlAttribList &tagHtmlAttribs); + +//--------------------------------------------------------------------------- static void docParserPushContext(bool saveParamInfo=TRUE) { //QCString indent; @@ -262,7 +269,7 @@ static void unescapeCRef(QCString &s) * copies the image to the output directory (which depends on the \a type * parameter). */ -static QCString findAndCopyImage(const char *fileName,DocImage::Type type) +static QCString findAndCopyImage(const char *fileName,DocImage::Type type, bool dowarn = true) { QCString result; bool ambig; @@ -330,7 +337,8 @@ static QCString findAndCopyImage(const char *fileName,DocImage::Type type) } else { - printf("Source & Destination are the same!\n"); + warn(g_fileName,doctokenizerYYlineno, + "Prevented to copy file %s onto itself!\n",qPrint(inputFile)); } } else @@ -358,7 +366,7 @@ static QCString findAndCopyImage(const char *fileName,DocImage::Type type) return baseName; } } - else if (ambig) + else if (ambig && dowarn) { QCString text; text.sprintf("image file name %s is ambiguous.\n",qPrint(fileName)); @@ -369,7 +377,7 @@ static QCString findAndCopyImage(const char *fileName,DocImage::Type type) else { result=fileName; - if (result.left(5)!="http:" && result.left(6)!="https:") + if (result.left(5)!="http:" && result.left(6)!="https:" && dowarn) { warn_doc_error(g_fileName,doctokenizerYYlineno, "image file %s is not found in IMAGE_PATH: " @@ -423,7 +431,7 @@ static void checkArgumentName(const QCString &name,bool isParam) } if (!found && isParam) { - //printf("member type=%d\n",memberDef->memberType()); + //printf("member type=%d\n",g_memberDef->memberType()); QCString scope=g_memberDef->getScopeString(); if (!scope.isEmpty()) scope+="::"; else scope=""; QCString inheritedFrom = ""; @@ -451,11 +459,12 @@ static void checkArgumentName(const QCString &name,bool isParam) } /*! Checks if the parameters that have been specified using \@param are - * indeed all parameters. + * indeed all parameters and that a parameter does not have multiple + * \@param blocks. * Must be called after checkArgumentName() has been called for each * argument. */ -static void checkUndocumentedParams() +static void checkUnOrMultipleDocumentedParams() { if (g_memberDef && g_hasParamCommand && Config_getBool(WARN_IF_DOC_ERROR)) { @@ -470,18 +479,37 @@ static void checkUndocumentedParams() bool found=FALSE; for (ali.toFirst();(a=ali.current());++ali) { + int count = 0; QCString argName = g_memberDef->isDefine() ? a->type : a->name; if (lang==SrcLangExt_Fortran) argName = argName.lower(); argName=argName.stripWhiteSpace(); + QCString aName = argName; if (argName.right(3)=="...") argName=argName.left(argName.length()-3); - if (g_memberDef->getLanguage()==SrcLangExt_Python && (argName=="self" || argName=="cls")) + if (lang==SrcLangExt_Python && (argName=="self" || argName=="cls")) { // allow undocumented self / cls parameter for Python } else if (!argName.isEmpty() && g_paramsFound.find(argName)==0 && a->docs.isEmpty()) { found = TRUE; - break; + } + else + { + QDictIterator<void> it1(g_paramsFound); + void *item1; + for (;(item1=it1.current());++it1) + { + if (argName == it1.currentKey()) count++; + } + } + if (count > 1) + { + warn_doc_error(g_memberDef->getDefFileName(), + g_memberDef->getDefLine(), + "argument '" + aName + + "' from the argument list of " + + QCString(g_memberDef->qualifiedName()) + + " has muliple @param documentation sections"); } } if (found) @@ -497,7 +525,7 @@ static void checkUndocumentedParams() QCString argName = g_memberDef->isDefine() ? a->type : a->name; if (lang==SrcLangExt_Fortran) argName = argName.lower(); argName=argName.stripWhiteSpace(); - if (g_memberDef->getLanguage()==SrcLangExt_Python && (argName=="self" || argName=="cls")) + if (lang==SrcLangExt_Python && (argName=="self" || argName=="cls")) { // allow undocumented self / cls parameter for Python } @@ -842,7 +870,31 @@ static bool findDocsForMemberOrCompound(const char *commandName, return FALSE; } //--------------------------------------------------------------------------- +inline void errorHandleDefaultToken(DocNode *parent,int tok, + QList<DocNode> &children,const char *txt) +{ + switch (tok) + { + case TK_COMMAND_AT: + // fall through + case TK_COMMAND_BS: + children.append(new DocWord(parent,TK_COMMAND_CHAR(tok) + g_token->name)); + warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a %s", + qPrint(TK_COMMAND_CHAR(tok) + g_token->name), txt); + break; + case TK_SYMBOL: + warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found found as part of a %s", + qPrint(g_token->name), txt); + break; + default: + children.append(new DocWord(parent,g_token->name)); + warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s found as part of a %s", + tokToString(tok), txt); + break; + } +} +//--------------------------------------------------------------------------- // forward declaration static bool defaultHandleToken(DocNode *parent,int tok, QList<DocNode> &children,bool @@ -852,6 +904,7 @@ static int handleStyleArgument(DocNode *parent,QList<DocNode> &children, const QCString &cmdName) { DBG(("handleStyleArgument(%s)\n",qPrint(cmdName))); + QCString saveCmdName = cmdName; int tok=doctokenizerYYlex(); if (tok!=TK_WHITESPACE) { @@ -877,14 +930,6 @@ static int handleStyleArgument(DocNode *parent,QList<DocNode> &children, { switch (tok) { - case TK_COMMAND: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command \\%s as the argument of a \\%s command", - qPrint(g_token->name),qPrint(cmdName)); - break; - case TK_SYMBOL: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found while handling command %s", - qPrint(g_token->name),qPrint(cmdName)); - break; case TK_HTMLTAG: if (insideLI(parent) && Mappers::htmlTagMapper->map(g_token->name) && g_token->endTag) { // ignore </li> as the end of a style command @@ -893,8 +938,7 @@ static int handleStyleArgument(DocNode *parent,QList<DocNode> &children, return tok; break; default: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s while handling command %s", - tokToString(tok),qPrint(cmdName)); + errorHandleDefaultToken(parent,tok,children,"\\" + saveCmdName + " command"); break; } break; @@ -1027,16 +1071,18 @@ const char *DocStyleChange::styleString() const { switch (m_style) { - case DocStyleChange::Bold: return "b"; - case DocStyleChange::Italic: return "em"; - case DocStyleChange::Code: return "code"; - case DocStyleChange::Center: return "center"; - case DocStyleChange::Small: return "small"; - case DocStyleChange::Subscript: return "subscript"; - case DocStyleChange::Superscript: return "superscript"; - case DocStyleChange::Preformatted: return "pre"; + case DocStyleChange::Bold: return "b"; + case DocStyleChange::Italic: return "em"; + case DocStyleChange::Code: return "code"; + case DocStyleChange::Center: return "center"; + case DocStyleChange::Small: return "small"; + case DocStyleChange::Subscript: return "subscript"; + case DocStyleChange::Superscript: return "superscript"; + case DocStyleChange::Preformatted: return "pre"; case DocStyleChange::Div: return "div"; case DocStyleChange::Span: return "span"; + case DocStyleChange::Strike: return "strike"; + case DocStyleChange::Underline: return "u"; } return "<invalid>"; } @@ -1271,21 +1317,7 @@ static void defaultHandleTitleAndSize(const int cmd, DocNode *parent, QList<DocN } if (!defaultHandleToken(parent,tok,children)) { - switch (tok) - { - case TK_COMMAND: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a \\%s", - qPrint(g_token->name), Mappers::cmdMapper->find(cmd).data()); - break; - case TK_SYMBOL: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found", - qPrint(g_token->name)); - break; - default: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s", - tokToString(tok)); - break; - } + errorHandleDefaultToken(parent,tok,children,Mappers::cmdMapper->find(cmd).data()); } } // parse size attributes @@ -1343,8 +1375,8 @@ static bool defaultHandleToken(DocNode *parent,int tok, QList<DocNode> &children handleWord) { DBG(("token %s at %d",tokToString(tok),doctokenizerYYlineno)); - if (tok==TK_WORD || tok==TK_LNKWORD || tok==TK_SYMBOL || tok==TK_URL || - tok==TK_COMMAND || tok==TK_HTMLTAG + if (tok==TK_WORD || tok==TK_LNKWORD || tok==TK_SYMBOL || tok==TK_URL || + tok==TK_COMMAND_AT || tok==TK_COMMAND_BS || tok==TK_HTMLTAG ) { DBG((" name=%s",qPrint(g_token->name))); @@ -1354,7 +1386,9 @@ reparsetoken: QCString tokenName = g_token->name; switch (tok) { - case TK_COMMAND: + case TK_COMMAND_AT: + // fall through + case TK_COMMAND_BS: switch (Mappers::cmdMapper->map(tokenName)) { case CMD_BSLASH: @@ -1405,6 +1439,9 @@ reparsetoken: case CMD_MINUS: children.append(new DocSymbol(parent,DocSymbol::Sym_Minus)); break; + case CMD_EQUAL: + children.append(new DocSymbol(parent,DocSymbol::Sym_Equal)); + break; case CMD_EMPHASIS: { children.append(new DocStyleChange(parent,g_nodeStack.count(),DocStyleChange::Italic,TRUE)); @@ -1538,6 +1575,9 @@ reparsetoken: doctokenizerYYsetStatePara(); } break; + case CMD_IMAGE: + ((DocPara *)parent) -> handleImage("image"); + break; default: return FALSE; } @@ -1562,6 +1602,26 @@ reparsetoken: handleStyleLeave(parent,children,DocStyleChange::Bold,tokenName); } break; + case HTML_STRIKE: + if (!g_token->endTag) + { + handleStyleEnter(parent,children,DocStyleChange::Strike,&g_token->attribs); + } + else + { + handleStyleLeave(parent,children,DocStyleChange::Strike,tokenName); + } + break; + case HTML_UNDERLINE: + if (!g_token->endTag) + { + handleStyleEnter(parent,children,DocStyleChange::Underline,&g_token->attribs); + } + else + { + handleStyleLeave(parent,children,DocStyleChange::Underline,tokenName); + } + break; case HTML_CODE: case XML_C: if (!g_token->endTag) @@ -1623,6 +1683,10 @@ reparsetoken: handleStyleLeave(parent,children,DocStyleChange::Small,tokenName); } break; + case HTML_IMG: + if (!g_token->endTag) + handleImg(parent,children,g_token->attribs); + break; default: return FALSE; break; @@ -1700,7 +1764,8 @@ static void handleImg(DocNode *parent,QList<DocNode> &children,const HtmlAttribL // and remove the src attribute bool result = attrList.remove(index); ASSERT(result); - DocImage *img = new DocImage(parent,attrList,opt->value,DocImage::Html,opt->value); + DocImage::Type t = DocImage::Html; + DocImage *img = new DocImage(parent,attrList,findAndCopyImage(opt->value,t,false),t,opt->value); children.append(img); found = TRUE; } @@ -1721,6 +1786,27 @@ DocSymbol::SymType DocSymbol::decodeSymbol(const QCString &symName) //--------------------------------------------------------------------------- +DocEmoji::DocEmoji(DocNode *parent,const QCString &symName) : + m_symName(symName), m_index(-1) +{ + m_parent = parent; + QCString locSymName = symName; + int len=locSymName.length(); + if (len>0) + { + if (locSymName.at(len-1)!=':') locSymName.append(":"); + if (locSymName.at(0)!=':') locSymName.prepend(":"); + } + m_symName = locSymName; + m_index = EmojiEntityMapper::instance()->symbol2index(m_symName); + if (m_index==-1) + { + warn_doc_error(g_fileName,doctokenizerYYlineno,"Found unsupported emoji symbol '%s'\n",qPrint(m_symName)); + } +} + +//--------------------------------------------------------------------------- + static int internalValidatingParseDoc(DocNode *parent,QList<DocNode> &children, const QCString &doc) { @@ -1850,11 +1936,8 @@ DocAnchor::DocAnchor(DocNode *parent,const QCString &id,bool newAnchor) { warn_doc_error(g_fileName,doctokenizerYYlineno,"Empty anchor label"); } - if (newAnchor) // found <a name="label"> - { - m_anchor = id; - } - else if (id.left(CiteConsts::anchorPrefix.length()) == CiteConsts::anchorPrefix) + + if (id.left(CiteConsts::anchorPrefix.length()) == CiteConsts::anchorPrefix) { CiteInfo *cite = Doxygen::citeDict->find(id.mid(CiteConsts::anchorPrefix.length())); if (cite) @@ -1869,6 +1952,10 @@ DocAnchor::DocAnchor(DocNode *parent,const QCString &id,bool newAnchor) m_file = "invalid"; } } + else if (newAnchor) // found <a name="label"> + { + m_anchor = id; + } else // found \anchor label { SectionInfo *sec = Doxygen::sectionDict->find(id); @@ -2280,21 +2367,7 @@ void DocSecRefItem::parse() { if (!defaultHandleToken(this,tok,m_children)) { - switch (tok) - { - case TK_COMMAND: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a \\refitem", - qPrint(g_token->name)); - break; - case TK_SYMBOL: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found", - qPrint(g_token->name)); - break; - default: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s", - tokToString(tok)); - break; - } + errorHandleDefaultToken(this,tok,m_children,"\\refitem"); } } doctokenizerYYsetStatePara(); @@ -2342,7 +2415,7 @@ void DocSecRefList::parse() // handle items while (tok) { - if (tok==TK_COMMAND) + if (tok==TK_COMMAND_AT || tok == TK_COMMAND_BS) { switch (Mappers::cmdMapper->map(g_token->name)) { @@ -2422,21 +2495,7 @@ void DocInternalRef::parse() { if (!defaultHandleToken(this,tok,m_children)) { - switch (tok) - { - case TK_COMMAND: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a \\ref", - qPrint(g_token->name)); - break; - case TK_SYMBOL: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found", - qPrint(g_token->name)); - break; - default: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s", - tokToString(tok)); - break; - } + errorHandleDefaultToken(this,tok,m_children,"\\ref"); } } @@ -2580,19 +2639,10 @@ void DocRef::parse() { switch (tok) { - case TK_COMMAND: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a \\ref", - qPrint(g_token->name)); - break; - case TK_SYMBOL: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found", - qPrint(g_token->name)); - break; case TK_HTMLTAG: break; default: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s", - tokToString(tok)); + errorHandleDefaultToken(this,tok,m_children,"\\ref"); break; } } @@ -2703,7 +2753,9 @@ QCString DocLink::parse(bool isJavaLink,bool isXmlLink) { switch (tok) { - case TK_COMMAND: + case TK_COMMAND_AT: + // fall through + case TK_COMMAND_BS: switch (Mappers::cmdMapper->map(g_token->name)) { case CMD_ENDLINK: @@ -2719,13 +2771,13 @@ QCString DocLink::parse(bool isJavaLink,bool isXmlLink) } break; case TK_SYMBOL: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found", + warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found as part of a \\link", qPrint(g_token->name)); break; case TK_HTMLTAG: if (g_token->name!="see" || !isXmlLink) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected xml/html command %s found", + warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected xml/html command %s found as part of a \\link", qPrint(g_token->name)); } goto endlink; @@ -2903,21 +2955,7 @@ void DocVhdlFlow::parse() { if (!defaultHandleToken(this,tok,m_children)) { - switch (tok) - { - case TK_COMMAND: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a \\vhdlflow", - qPrint(g_token->name)); - break; - case TK_SYMBOL: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found", - qPrint(g_token->name)); - break; - default: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s", - tokToString(tok)); - break; - } + errorHandleDefaultToken(this,tok,m_children,"\\vhdlflow"); } } tok=doctokenizerYYlex(); @@ -2935,10 +2973,10 @@ void DocVhdlFlow::parse() //--------------------------------------------------------------------------- DocImage::DocImage(DocNode *parent,const HtmlAttribList &attribs,const QCString &name, - Type t,const QCString &url) : - m_attribs(attribs), m_name(name), + Type t,const QCString &url, bool inlineImage) : + m_attribs(attribs), m_name(name), m_type(t), m_relPath(g_relPath), - m_url(url) + m_url(url), m_inlineImage(inlineImage) { m_parent = parent; } @@ -2964,10 +3002,6 @@ int DocHtmlHeader::parse() { switch (tok) { - case TK_COMMAND: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a <h%d> tag", - qPrint(g_token->name),m_level); - break; case TK_HTMLTAG: { int tagId=Mappers::htmlTagMapper->map(g_token->name); @@ -3042,17 +3076,12 @@ int DocHtmlHeader::parse() warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected html tag <%s%s> found within <h%d> context", g_token->endTag?"/":"",qPrint(g_token->name),m_level); } - } break; - case TK_SYMBOL: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found", - qPrint(g_token->name)); - break; default: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s", - tokToString(tok)); - break; + char tmp[20]; + sprintf(tmp,"<h%d>tag",m_level); + errorHandleDefaultToken(this,tok,m_children,tmp); } } } @@ -3084,16 +3113,7 @@ int DocHRef::parse() { switch (tok) { - case TK_COMMAND: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a <a>..</a> block", - qPrint(g_token->name)); - break; - case TK_SYMBOL: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found", - qPrint(g_token->name)); - break; case TK_HTMLTAG: - { int tagId=Mappers::htmlTagMapper->map(g_token->name); if (tagId==HTML_A && g_token->endTag) // found </a> tag @@ -3108,8 +3128,7 @@ int DocHRef::parse() } break; default: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s", - tokToString(tok),doctokenizerYYlineno); + errorHandleDefaultToken(this,tok,m_children,"<a>..</a> block"); break; } } @@ -3242,29 +3261,32 @@ int DocIndexEntry::parse() } } break; - case TK_COMMAND: - switch (Mappers::cmdMapper->map(g_token->name)) - { - case CMD_BSLASH: m_entry+='\\'; break; - case CMD_AT: m_entry+='@'; break; - case CMD_LESS: m_entry+='<'; break; - case CMD_GREATER: m_entry+='>'; break; - case CMD_AMP: m_entry+='&'; break; - case CMD_DOLLAR: m_entry+='$'; break; - case CMD_HASH: m_entry+='#'; break; - case CMD_DCOLON: m_entry+="::"; break; - case CMD_PERCENT: m_entry+='%'; break; - case CMD_NDASH: m_entry+="--"; break; - case CMD_MDASH: m_entry+="---"; break; - case CMD_QUOTE: m_entry+='"'; break; - case CMD_PUNT: m_entry+='.'; break; - case CMD_PLUS: m_entry+='+'; break; - case CMD_MINUS: m_entry+='-'; break; - default: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected command %s found as argument of \\addindex", - qPrint(g_token->name)); - break; - } + case TK_COMMAND_AT: + // fall through + case TK_COMMAND_BS: + switch (Mappers::cmdMapper->map(g_token->name)) + { + case CMD_BSLASH: m_entry+='\\'; break; + case CMD_AT: m_entry+='@'; break; + case CMD_LESS: m_entry+='<'; break; + case CMD_GREATER: m_entry+='>'; break; + case CMD_AMP: m_entry+='&'; break; + case CMD_DOLLAR: m_entry+='$'; break; + case CMD_HASH: m_entry+='#'; break; + case CMD_DCOLON: m_entry+="::"; break; + case CMD_PERCENT: m_entry+='%'; break; + case CMD_NDASH: m_entry+="--"; break; + case CMD_MDASH: m_entry+="---"; break; + case CMD_QUOTE: m_entry+='"'; break; + case CMD_PUNT: m_entry+='.'; break; + case CMD_PLUS: m_entry+='+'; break; + case CMD_MINUS: m_entry+='-'; break; + case CMD_EQUAL: m_entry+='='; break; + default: + warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected command %s found as argument of \\addindex", + qPrint(g_token->name)); + break; + } break; default: warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s", @@ -3330,14 +3352,6 @@ int DocHtmlCaption::parse() { switch (tok) { - case TK_COMMAND: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a <caption> tag", - qPrint(g_token->name)); - break; - case TK_SYMBOL: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found", - qPrint(g_token->name)); - break; case TK_HTMLTAG: { int tagId=Mappers::htmlTagMapper->map(g_token->name); @@ -3354,8 +3368,7 @@ int DocHtmlCaption::parse() } break; default: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s", - tokToString(tok)); + errorHandleDefaultToken(this,tok,m_children,"<caption> tag"); break; } } @@ -3485,14 +3498,34 @@ DocHtmlCell::Alignment DocHtmlCell::alignment() const { HtmlAttribList attrs = attribs(); uint i; - for (i=0; i<attrs.count(); ++i) + for (i=0; i<attrs.count(); ++i) { if (attrs.at(i)->name.lower()=="align") { - if (attrs.at(i)->value.lower()=="center") + if (attrs.at(i)->value.lower()=="center") + return Center; + else if (attrs.at(i)->value.lower()=="right") + return Right; + else return Left; + } + else if (attrs.at(i)->name.lower()=="class") + { + if (attrs.at(i)->value.lower()=="markdowntableheadcenter") + return Center; + else if (attrs.at(i)->value.lower()=="markdowntableheadright") + return Right; + else if (attrs.at(i)->value.lower()=="markdowntableheadleft") + return Left; + else if (attrs.at(i)->value.lower()=="markdowntableheadnone") + return Center; + else if (attrs.at(i)->value.lower()=="markdowntablebodycenter") return Center; - else if (attrs.at(i)->value.lower()=="right") + else if (attrs.at(i)->value.lower()=="markdowntablebodyright") return Right; + else if (attrs.at(i)->value.lower()=="markdowntablebodyleft") + return Left; + else if (attrs.at(i)->value.lower()=="markdowntablebodynone") + return Left; else return Left; } } @@ -3849,7 +3882,9 @@ int DocHtmlDescTitle::parse() { switch (tok) { - case TK_COMMAND: + case TK_COMMAND_AT: + // fall through + case TK_COMMAND_BS: { QCString cmdName=g_token->name; bool isJavaLink=FALSE; @@ -3860,7 +3895,7 @@ int DocHtmlDescTitle::parse() int tok=doctokenizerYYlex(); if (tok!=TK_WHITESPACE) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after %s command", + warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after \\%s command", qPrint(g_token->name)); } else @@ -3869,7 +3904,7 @@ int DocHtmlDescTitle::parse() tok=doctokenizerYYlex(); // get the reference id if (tok!=TK_WORD) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token %s as the argument of %s", + warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token %s as the argument of \\%s command", tokToString(tok),qPrint(cmdName)); } else @@ -3890,7 +3925,7 @@ int DocHtmlDescTitle::parse() int tok=doctokenizerYYlex(); if (tok!=TK_WHITESPACE) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after %s command", + warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after \\%s command", qPrint(cmdName)); } else @@ -3899,7 +3934,7 @@ int DocHtmlDescTitle::parse() tok=doctokenizerYYlex(); if (tok!=TK_WORD) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token %s as the argument of %s", + warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token %s as the argument of \\%s command", tokToString(tok),qPrint(cmdName)); } else @@ -3918,13 +3953,13 @@ int DocHtmlDescTitle::parse() break; default: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a <dt> tag", + warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command \\%s found as part of a <dt> tag", qPrint(g_token->name)); } } break; case TK_SYMBOL: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found", + warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol \\%s found as part of a <dt> tag", qPrint(g_token->name)); break; case TK_HTMLTAG: @@ -3965,7 +4000,7 @@ int DocHtmlDescTitle::parse() } break; default: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s", + warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s found as part of a <dt> tag", tokToString(tok)); break; } @@ -4470,21 +4505,7 @@ void DocTitle::parse() { if (!defaultHandleToken(this,tok,m_children)) { - switch (tok) - { - case TK_COMMAND: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a title section", - qPrint(g_token->name)); - break; - case TK_SYMBOL: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found", - qPrint(g_token->name)); - break; - default: - warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s", - tokToString(tok)); - break; - } + errorHandleDefaultToken(this,tok,m_children,"title section"); } } doctokenizerYYsetStatePara(); @@ -4940,6 +4961,35 @@ void DocPara::handleCite() doctokenizerYYsetStatePara(); } +void DocPara::handleEmoji() +{ + // get the argument of the emoji command. + int tok=doctokenizerYYlex(); + if (tok!=TK_WHITESPACE) + { + warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after %s command", + qPrint("emoji")); + return; + } + doctokenizerYYsetStateEmoji(); + tok=doctokenizerYYlex(); + if (tok==0) + { + warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected end of comment block while parsing the " + "argument of command %s\n", qPrint("emoji")); + return; + } + else if (tok!=TK_WORD) + { + warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token %s as the argument of %s", + tokToString(tok),qPrint("emoji")); + return; + } + DocEmoji *emoji = new DocEmoji(this,g_token->name); + m_children.append(emoji); + doctokenizerYYsetStatePara(); +} + int DocPara::handleXRefItem() { int retval=doctokenizerYYlex(); @@ -5017,25 +5067,64 @@ void DocPara::handleIncludeOperator(const QCString &cmdName,DocIncOperator::Type void DocPara::handleImage(const QCString &cmdName) { + QCString saveCmdName = cmdName; + bool inlineImage = FALSE; + int tok=doctokenizerYYlex(); if (tok!=TK_WHITESPACE) { - warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after %s command", - qPrint(cmdName)); - return; + if (tok==TK_WORD) + { + if (g_token->name == "{") + { + while ((tok=doctokenizerYYlex())==TK_WHITESPACE); + if (g_token->name != "}") // non-empty option string + { + if (g_token->name.lower() != "inline") + { + warn_doc_error(g_fileName,doctokenizerYYlineno,"currently only 'inline' suported as option of %s command", + qPrint(saveCmdName)); + } + else + { + inlineImage = TRUE; + } + while ((tok=doctokenizerYYlex())==TK_WHITESPACE); + } + if (!((tok==TK_WORD) && (g_token->name == "}"))) + { + warn_doc_error(g_fileName,doctokenizerYYlineno,"expected closing '}' at option of %s command", + qPrint(saveCmdName)); + return; + } + tok=doctokenizerYYlex(); + if (tok!=TK_WHITESPACE) + { + warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after %s command with option", + qPrint(saveCmdName)); + return; + } + } + } + else + { + warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after %s command", + qPrint(saveCmdName)); + return; + } } tok=doctokenizerYYlex(); if (tok!=TK_WORD && tok!=TK_LNKWORD) { warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token %s as the argument of %s", - tokToString(tok),qPrint(cmdName)); + tokToString(tok),qPrint(saveCmdName)); return; } tok=doctokenizerYYlex(); if (tok!=TK_WHITESPACE) { warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after %s command", - qPrint(cmdName)); + qPrint(saveCmdName)); return; } DocImage::Type t; @@ -5046,9 +5135,9 @@ void DocPara::handleImage(const QCString &cmdName) else if (imgType=="rtf") t=DocImage::Rtf; else { - warn_doc_error(g_fileName,doctokenizerYYlineno,"image type %s specified as the first argument of " - "%s is not valid", - qPrint(imgType),qPrint(cmdName)); + warn_doc_error(g_fileName,doctokenizerYYlineno,"output format %s specified as the first argument of " + "%s command is not valid", + qPrint(imgType),qPrint(saveCmdName)); return; } doctokenizerYYsetStateFile(); @@ -5057,11 +5146,11 @@ void DocPara::handleImage(const QCString &cmdName) if (tok!=TK_WORD) { warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token %s as the argument of %s", - tokToString(tok),qPrint(cmdName)); + tokToString(tok),qPrint(saveCmdName)); return; } HtmlAttribList attrList; - DocImage *img = new DocImage(this,attrList,findAndCopyImage(g_token->name,t),t); + DocImage *img = new DocImage(this,attrList,findAndCopyImage(g_token->name,t),t,"",inlineImage); m_children.append(img); img->parse(); } @@ -5155,7 +5244,40 @@ void DocPara::handleInclude(const QCString &cmdName,DocInclude::Type t) { DBG(("handleInclude(%s)\n",qPrint(cmdName))); int tok=doctokenizerYYlex(); - if (tok!=TK_WHITESPACE) + bool isBlock = false; + if (tok==TK_WORD && g_token->name=="{") + { + doctokenizerYYsetStateOptions(); + tok=doctokenizerYYlex(); + doctokenizerYYsetStatePara(); + QCStringList optList=QCStringList::split(",",g_token->name); + if (t==DocInclude::Include && optList.contains("lineno")) + { + t = DocInclude::IncWithLines; + } + else if (t==DocInclude::Snippet && optList.contains("lineno")) + { + t = DocInclude::SnipWithLines; + } + else if (t==DocInclude::Include && optList.contains("doc")) + { + t = DocInclude::IncludeDoc; + } + else if (t==DocInclude::Snippet && optList.contains("doc")) + { + t = DocInclude::SnippetDoc; + } + tok=doctokenizerYYlex(); + } + else if (tok==TK_WORD && g_token->name=="[") + { + doctokenizerYYsetStateBlock(); + tok=doctokenizerYYlex(); + isBlock = (g_token->name.stripWhiteSpace() == "block"); + doctokenizerYYsetStatePara(); + tok=doctokenizerYYlex(); + } + else if (tok!=TK_WHITESPACE) { warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after %s command", qPrint(cmdName)); @@ -5213,7 +5335,7 @@ void DocPara::handleInclude(const QCString &cmdName,DocInclude::Type t) } else { - DocInclude *inc = new DocInclude(this,fileName,g_context,t,g_isExample,g_exampleName,blockId); + DocInclude *inc = new DocInclude(this,fileName,g_context,t,g_isExample,g_exampleName,blockId,isBlock); m_children.append(inc); inc->parse(); } @@ -5319,7 +5441,7 @@ void DocPara::handleInheritDoc() } -int DocPara::handleCommand(const QCString &cmdName) +int DocPara::handleCommand(const QCString &cmdName, const int tok) { DBG(("handleCommand(%s)\n",qPrint(cmdName))); int retval = RetVal_OK; @@ -5327,6 +5449,7 @@ int DocPara::handleCommand(const QCString &cmdName) switch (cmdId) { case CMD_UNKNOWN: + m_children.append(new DocWord(this,TK_COMMAND_CHAR(tok) + cmdName)); warn_doc_error(g_fileName,doctokenizerYYlineno,"Found unknown command `\\%s'",qPrint(cmdName)); break; case CMD_EMPHASIS: @@ -5398,6 +5521,9 @@ int DocPara::handleCommand(const QCString &cmdName) case CMD_MINUS: m_children.append(new DocSymbol(this,DocSymbol::Sym_Minus)); break; + case CMD_EQUAL: + m_children.append(new DocSymbol(this,DocSymbol::Sym_Equal)); + break; case CMD_SA: g_inSeeBlock=TRUE; retval = handleSimpleSection(DocSimpleSect::See); @@ -5593,7 +5719,8 @@ int DocPara::handleCommand(const QCString &cmdName) defaultHandleTitleAndSize(CMD_STARTUML,dv,dv->children(),width,height); doctokenizerYYsetStatePlantUML(); retval = doctokenizerYYlex(); - dv->setText(g_token->verb); + int line=0; + dv->setText(stripLeadingAndTrailingEmptyLines(g_token->verb,line)); dv->setWidth(width); dv->setHeight(height); if (jarPath.isEmpty()) @@ -5750,6 +5877,9 @@ int DocPara::handleCommand(const QCString &cmdName) case CMD_CITE: handleCite(); break; + case CMD_EMOJI: + handleEmoji(); + break; case CMD_REF: // fall through case CMD_SUBPAGE: handleRef(cmdName); @@ -5863,6 +5993,12 @@ int DocPara::handleHtmlStartTag(const QCString &tagName,const HtmlAttribList &ta case HTML_BOLD: handleStyleEnter(this,m_children,DocStyleChange::Bold,&g_token->attribs); break; + case HTML_STRIKE: + handleStyleEnter(this,m_children,DocStyleChange::Strike,&g_token->attribs); + break; + case HTML_UNDERLINE: + handleStyleEnter(this,m_children,DocStyleChange::Underline,&g_token->attribs); + break; case HTML_CODE: if (/*getLanguageFromFileName(g_fileName)==SrcLangExt_CSharp ||*/ g_xmlComment) // for C# source or inside a <summary> or <remark> section we @@ -6125,16 +6261,15 @@ int DocPara::handleHtmlStartTag(const QCString &tagName,const HtmlAttribList &ta } } } - else if (findAttribute(tagHtmlAttribs,"langword",&cref)) // <see langword="..."/> or <see langworld="..."></see> + else if (findAttribute(tagHtmlAttribs,"langword",&cref)) // <see langword="..."/> or <see langword="..."></see> { - doctokenizerYYsetStatePara(); - DocLink *lnk = new DocLink(this,cref); - m_children.append(lnk); - QCString leftOver = lnk->parse(FALSE,TRUE); - if (!leftOver.isEmpty()) - { - m_children.append(new DocWord(this,leftOver)); - } + bool inSeeBlock = g_inSeeBlock; + g_token->name = cref; + g_inSeeBlock = TRUE; + m_children.append(new DocStyleChange(this,g_nodeStack.count(),DocStyleChange::Code,TRUE)); + handleLinkedWord(this,m_children,TRUE); + m_children.append(new DocStyleChange(this,g_nodeStack.count(),DocStyleChange::Code,FALSE)); + g_inSeeBlock = inSeeBlock; } else { @@ -6273,6 +6408,12 @@ int DocPara::handleHtmlEndTag(const QCString &tagName) case HTML_BOLD: handleStyleLeave(this,m_children,DocStyleChange::Bold,"b"); break; + case HTML_STRIKE: + handleStyleLeave(this,m_children,DocStyleChange::Strike,"strike"); + break; + case HTML_UNDERLINE: + handleStyleLeave(this,m_children,DocStyleChange::Underline,"u"); + break; case HTML_CODE: handleStyleLeave(this,m_children,DocStyleChange::Code,"code"); break; @@ -6416,8 +6557,8 @@ int DocPara::parse() { reparsetoken: DBG(("token %s at %d",tokToString(tok),doctokenizerYYlineno)); - if (tok==TK_WORD || tok==TK_LNKWORD || tok==TK_SYMBOL || tok==TK_URL || - tok==TK_COMMAND || tok==TK_HTMLTAG + if (tok==TK_WORD || tok==TK_LNKWORD || tok==TK_SYMBOL || tok==TK_URL || + tok==TK_COMMAND_AT || tok == TK_COMMAND_BS || tok==TK_HTMLTAG ) { DBG((" name=%s",qPrint(g_token->name))); @@ -6515,7 +6656,7 @@ reparsetoken: } else // other section { - tok = TK_COMMAND; + tok = TK_COMMAND_BS; } DBG(("reparsing command %s\n",qPrint(g_token->name))); goto reparsetoken; @@ -6560,7 +6701,9 @@ reparsetoken: "list items"); } break; - case TK_COMMAND: + case TK_COMMAND_AT: + // fall through + case TK_COMMAND_BS: { // see if we have to start a simple section int cmd = Mappers::cmdMapper->map(g_token->name); @@ -6596,7 +6739,7 @@ reparsetoken: } // handle the command - retval=handleCommand(g_token->name); + retval=handleCommand(g_token->name,tok); DBG(("handleCommand returns %x\n",retval)); // check the return value @@ -6614,7 +6757,7 @@ reparsetoken: } else // other section { - tok = TK_COMMAND; + tok = TK_COMMAND_BS; } DBG(("reparsing command %s\n",qPrint(g_token->name))); goto reparsetoken; @@ -6886,7 +7029,9 @@ void DocText::parse() } } break; - case TK_COMMAND: + case TK_COMMAND_AT: + // fall through + case TK_COMMAND_BS: switch (Mappers::cmdMapper->map(g_token->name)) { case CMD_BSLASH: @@ -6937,6 +7082,9 @@ void DocText::parse() case CMD_MINUS: m_children.append(new DocSymbol(this,DocSymbol::Sym_Minus)); break; + case CMD_EQUAL: + m_children.append(new DocSymbol(this,DocSymbol::Sym_Equal)); + break; default: warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected command `%s' found", qPrint(g_token->name)); @@ -7232,8 +7380,129 @@ static QCString processCopyDoc(const char *data,uint &len) buf.addChar(0); return buf.get(); } +//--------------------------------------------------------------------------- +QString::Direction getTextDirByConfig(const QString &text) +{ + QCString configDir = Config_getEnum(OUTPUT_TEXT_DIRECTION); + if (configDir == "None") + return QString::DirNeutral; + if (configDir == "Context") + return text.basicDirection(); + if (configDir == "LTR") + { + QString::Direction textDir = text.direction(); + if (textDir == QString::DirMixed) + return QString::DirLTR; + return textDir; + } + if (configDir == "RTL") + { + QString::Direction textDir = text.direction(); + if (textDir == QString::DirMixed) + return QString::DirRTL; + return textDir; + } + return QString::DirNeutral; +} -//-------------------------------------------------------------------------- +QString::Direction getTextDirByConfig(const DocNode *node) +{ + QCString configDir = Config_getEnum(OUTPUT_TEXT_DIRECTION); + if (configDir == "None") + return QString::DirNeutral; + if (configDir == "Context") + return node->getTextBasicDir(); + if (configDir == "LTR") + { + QString::Direction textDir = node->getTextDir(); + if (textDir == QString::DirMixed) + return QString::DirLTR; + return textDir; + } + if (configDir == "RTL") + { + QString::Direction textDir = node->getTextDir(); + if (textDir == QString::DirMixed) + return QString::DirRTL; + return textDir; + } + return QString::DirNeutral; +} + +QString::Direction getTextDirByConfig(const DocPara *para, int nodeIndex) +{ + QCString configDir = Config_getEnum(OUTPUT_TEXT_DIRECTION); + if (configDir == "None") + return QString::DirNeutral; + if (configDir == "Context") + return para->getTextBasicDir(nodeIndex); + if (configDir == "LTR") + { + QString::Direction textDir = para->getTextDir(nodeIndex); + if (textDir == QString::DirMixed) + return QString::DirLTR; + return textDir; + } + if (configDir == "RTL") + { + QString::Direction textDir = para->getTextDir(nodeIndex); + if (textDir == QString::DirMixed) + return QString::DirRTL; + return textDir; + } + return QString::DirNeutral; +} + +QCString getDirHtmlClassOfNode(QString::Direction textDir, const QCString &initValue) +{ + QCString classFromDir; + if (textDir == QString::DirLTR) + classFromDir = "DocNodeLTR"; + else if (textDir == QString::DirRTL) + classFromDir = "DocNodeRTL"; + else + classFromDir = ""; + + if (initValue && !classFromDir.isEmpty()) + return QCString(" class=\"") + initValue + " " + classFromDir + "\""; + if (initValue) + return QCString(" class=\"") + initValue + "\""; + if (!classFromDir.isEmpty()) + return QCString(" class=\"") + classFromDir + "\""; + return ""; +} + +QCString getDirHtmlClassOfPage(QCString pageTitle) +{ + QCString result = ""; + result += " class=\"PageDoc"; + QString::Direction titleDir = getTextDirByConfig(pageTitle); + if (titleDir == QString::DirLTR) + result += " PageDocLTR-title"; + else if (titleDir == QString::DirRTL) + result += " PageDocRTL-title"; + result += "\""; + return result; +} + +QCString getHtmlDirEmbedingChar(QString::Direction textDir) +{ + if (textDir == QString::DirLTR) + return "‪"; + if (textDir == QString::DirRTL) + return "‫"; + return ""; +} + +QCString getJsDirEmbedingChar(QString::Direction textDir) +{ + if (textDir == QString::DirLTR) + return "\\u202A"; + if (textDir == QString::DirRTL) + return "\\u202B"; + return ""; +} +//--------------------------------------------------------------------------- DocRoot *validatingParseDoc(const char *fileName,int startLine, Definition *ctx,MemberDef *md, @@ -7420,7 +7689,7 @@ DocRoot *validatingParseDoc(const char *fileName,int startLine, delete v; } - checkUndocumentedParams(); + checkUnOrMultipleDocumentedParams(); detectNoDocumentedParams(); // TODO: These should be called at the end of the program. |