From 64ac36480f407145d8fe1e96ea4cf8f7e30285d5 Mon Sep 17 00:00:00 2001 From: albert-github Date: Mon, 4 Feb 2019 19:31:01 +0100 Subject: Bug 136299 - attributes to

tag get lost Besides the `p` tag there were a number of other tags were also the attributes were lost: - `br` - `hr` - `a` in case of used as an anchor i.e. with the `name=` attribute In case of a `caption` with a `table` and no `id=` attribute with the `caption` there was still an anchor generated In scanner.l the warnings message was a bit unclear. --- src/docparser.cpp | 21 +++++++++++++++------ src/docparser.h | 23 ++++++++++++++++++++--- src/htmldocvisitor.cpp | 16 +++++++++------- src/scanner.l | 2 +- 4 files changed, 45 insertions(+), 17 deletions(-) diff --git a/src/docparser.cpp b/src/docparser.cpp index 20ee1f0..1cca00e 100644 --- a/src/docparser.cpp +++ b/src/docparser.cpp @@ -1037,7 +1037,12 @@ static int handleAHref(DocNode *parent,QList &children,const HtmlAttrib { if (!opt->value.isEmpty()) { - DocAnchor *anc = new DocAnchor(parent,opt->value,TRUE); + // copy attributes + HtmlAttribList attrList = tagHtmlAttribs; + // and remove the href attribute + bool result = attrList.remove(index); + ASSERT(result); + DocAnchor *anc = new DocAnchor(parent,opt->value,TRUE,attrList); children.append(anc); break; // stop looking for other tag attribs } @@ -1929,7 +1934,7 @@ DocLinkedWord::DocLinkedWord(DocNode *parent,const QCString &word, //--------------------------------------------------------------------------- -DocAnchor::DocAnchor(DocNode *parent,const QCString &id,bool newAnchor) +void DocAnchor::docAnchorInit(DocNode *parent,const QCString &id,bool newAnchor) { m_parent = parent; if (id.isEmpty()) @@ -3073,7 +3078,7 @@ int DocHtmlHeader::parse() } else if (tagId==HTML_BR) { - DocLineBreak *lb = new DocLineBreak(this); + DocLineBreak *lb = new DocLineBreak(this,g_token->attribs); m_children.append(lb); } else @@ -6080,13 +6085,13 @@ int DocPara::handleHtmlStartTag(const QCString &tagName,const HtmlAttribList &ta break; case HTML_BR: { - DocLineBreak *lb = new DocLineBreak(this); + DocLineBreak *lb = new DocLineBreak(this,tagHtmlAttribs); m_children.append(lb); } break; case HTML_HR: { - DocHorRuler *hr = new DocHorRuler(this); + DocHorRuler *hr = new DocHorRuler(this,tagHtmlAttribs); m_children.append(hr); } break; @@ -6861,6 +6866,10 @@ endparagraph: DocNode *n = g_nodeStack.pop(); ASSERT(n==this); DBG(("DocPara::parse() end retval=%x\n",retval)); + if (!g_token->endTag && retval == TK_NEWPARA && g_token->name.lower() == "p") + { + ((DocPara *)n) -> m_attribs = g_token->attribs; + } INTERNAL_ASSERT(retval==0 || retval==TK_NEWPARA || retval==TK_LISTITEM || retval==TK_ENDLIST || retval>RetVal_OK ); @@ -7128,7 +7137,7 @@ void DocRoot::parse() DocPara *par = new DocPara(this); if (isFirst) { par->markFirst(); isFirst=FALSE; } retval=par->parse(); - if (!par->isEmpty()) + if (!par->isEmpty() || par->attribs().count()) { m_children.append(par); lastPar=par; diff --git a/src/docparser.h b/src/docparser.h index 5d2cc89..7363232 100644 --- a/src/docparser.h +++ b/src/docparser.h @@ -300,37 +300,52 @@ class DocURL : public DocNode class DocLineBreak : public DocNode { public: - DocLineBreak(DocNode *parent) { m_parent=parent; } + DocLineBreak(DocNode *parent) { m_parent = parent; } + DocLineBreak(DocNode *parent,const HtmlAttribList &attribs) + : m_attribs(attribs) { m_parent = parent; } Kind kind() const { return Kind_LineBreak; } void accept(DocVisitor *v) { v->visit(this); } + const HtmlAttribList &attribs() const { return m_attribs; } + private: + HtmlAttribList m_attribs; }; /** Node representing a horizontal ruler */ class DocHorRuler : public DocNode { public: - DocHorRuler(DocNode *parent) { m_parent = parent; } + DocHorRuler(DocNode *parent,const HtmlAttribList &attribs) + : m_attribs(attribs) { m_parent = parent; } Kind kind() const { return Kind_HorRuler; } void accept(DocVisitor *v) { v->visit(this); } + const HtmlAttribList &attribs() const { return m_attribs; } + private: + HtmlAttribList m_attribs; }; /** Node representing an anchor */ class DocAnchor : public DocNode { public: - DocAnchor(DocNode *parent,const QCString &id,bool newAnchor); + DocAnchor(DocNode *parent,const QCString &id,bool newAnchor){docAnchorInit(parent,id,newAnchor);} + DocAnchor(DocNode *parent,const QCString &id,bool newAnchor,const HtmlAttribList &attribs) : m_attribs(attribs) + {docAnchorInit(parent,id,newAnchor);} Kind kind() const { return Kind_Anchor; } QCString anchor() const { return m_anchor; } QCString file() const { return m_file; } void accept(DocVisitor *v) { v->visit(this); } + const HtmlAttribList &attribs() const { return m_attribs; } + private: QCString m_anchor; QCString m_file; + HtmlAttribList m_attribs; + void docAnchorInit(DocNode *parent,const QCString &id,bool newAnchor); }; /** Node representing a citation of some bibliographic reference */ @@ -1199,11 +1214,13 @@ class DocPara : public CompAccept int handleHtmlHeader(const HtmlAttribList &tagHtmlAttribs,int level); bool injectToken(int tok,const QCString &tokText); + const HtmlAttribList &attribs() const { return m_attribs; } private: QCString m_sectionId; bool m_isFirst; bool m_isLast; + HtmlAttribList m_attribs; }; /** Node representing a parameter list. */ diff --git a/src/htmldocvisitor.cpp b/src/htmldocvisitor.cpp index 25166bc..67fc98d 100644 --- a/src/htmldocvisitor.cpp +++ b/src/htmldocvisitor.cpp @@ -350,17 +350,17 @@ void HtmlDocVisitor::visit(DocURL *u) } } -void HtmlDocVisitor::visit(DocLineBreak *) +void HtmlDocVisitor::visit(DocLineBreak *br) { if (m_hide) return; - m_t << "
\n"; + m_t << "
attribs()) << " />\n"; } void HtmlDocVisitor::visit(DocHorRuler *hr) { if (m_hide) return; forceEndParagraph(hr); - m_t << "


\n"; + m_t << "
attribs()) << " />\n"; forceStartParagraph(hr); } @@ -614,7 +614,7 @@ void HtmlDocVisitor::visit(DocVerbatim *s) void HtmlDocVisitor::visit(DocAnchor *anc) { if (m_hide) return; - m_t << "anchor() << "\">"; + m_t << "anchor() << "\"" << htmlAttribsToString(anc->attribs()) << ">"; } void HtmlDocVisitor::visit(DocInclude *inc) @@ -1206,9 +1206,9 @@ void HtmlDocVisitor::visitPre(DocPara *p) //printf(" needsTag=%d\n",needsTag); // write the paragraph tag (if needed) if (needsTag) - m_t << ""; + m_t << "attribs()) << ">"; else if(!paragraphAlreadyStarted) - m_t << getHtmlDirEmbedingChar(getTextDirByConfig(p)); + m_t << getHtmlDirEmbedingChar(getTextDirByConfig(p)) << htmlAttribsToString(p->attribs()); } void HtmlDocVisitor::visitPost(DocPara *p) @@ -1492,7 +1492,9 @@ void HtmlDocVisitor::visitPre(DocHtmlTable *t) if (t->hasCaption()) { - m_t << "caption()->anchor() << "\">\n"; + QCString anc = t->caption()->anchor(); + if (!anc.isEmpty()) + m_t << "\n"; } QString attrs = htmlAttribsToString(t->attribs()); diff --git a/src/scanner.l b/src/scanner.l index cad997e..3726023 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -6732,7 +6732,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } <> { warn(yyFileName,yyLineNr, - "reached end of file while inside a %s block!\n" + "reached end of file while inside a `%s' block!\n" "The command that should end the block seems to be missing!\n", docBlockName.data()); yyterminate(); -- cgit v0.12