From d5905871951cde51c6dcaa01d745de2f884ce9a9 Mon Sep 17 00:00:00 2001 From: Dimitri van Heesch Date: Sat, 26 Dec 2015 16:24:36 +0100 Subject: Bug 746162 - formulas creating invalid HTML code --- src/docparser.h | 14 ++++++++++--- src/htmldocvisitor.cpp | 55 ++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 58 insertions(+), 11 deletions(-) diff --git a/src/docparser.h b/src/docparser.h index 5af5e96..e2751d8 100644 --- a/src/docparser.h +++ b/src/docparser.h @@ -309,10 +309,18 @@ class DocCite : public DocNode class DocStyleChange : public DocNode { public: - enum Style { Bold, Italic, Code, Center, Small, - Subscript, Superscript, Preformatted, - Span, Div + enum Style { Bold = (1<<0), + Italic = (1<<1), + Code = (1<<2), + Center = (1<<3), + Small = (1<<4), + Subscript = (1<<5), + Superscript = (1<<6), + Preformatted = (1<<7), + Span = (1<<8), + Div = (1<<9) }; + DocStyleChange(DocNode *parent,uint position,Style s,bool enable, const HtmlAttribList *attribs=0) : m_position(position), m_style(s), m_enable(enable) diff --git a/src/htmldocvisitor.cpp b/src/htmldocvisitor.cpp index d1e4ffb..0533f87 100644 --- a/src/htmldocvisitor.cpp +++ b/src/htmldocvisitor.cpp @@ -42,7 +42,7 @@ static const char types[][NUM_HTML_LIST_TYPES] = {"1", "a", "i", "A"}; static QCString convertIndexWordToAnchor(const QString &word) { static char hex[] = "0123456789abcdef"; - QCString result; + QCString result="a"; const char *str = word.data(); unsigned char c; if (str) @@ -54,8 +54,7 @@ static QCString convertIndexWordToAnchor(const QString &word) (c >= '0' && c <= '9') || // DIGIT c == '-' || c == '.' || - c == '_' || - c == '~' + c == '_' ) { result += c; @@ -63,7 +62,7 @@ static QCString convertIndexWordToAnchor(const QString &word) else { char enc[4]; - enc[0] = '%'; + enc[0] = ':'; enc[1] = hex[(c & 0xf0) >> 4]; enc[2] = hex[c & 0xf]; enc[3] = 0; @@ -2044,6 +2043,42 @@ void HtmlDocVisitor::writePlantUMLFile(const QCString &fileName, } } +/** Returns TRUE if the child nodes in paragraph \a para until \a nodeIndex + contain a style change node that is still active and that style change is one that + must be located outside of a paragraph, i.e. it is a center, div, or pre tag. + See also bug746162. + */ +static bool insideStyleChangeThatIsOutsideParagraph(DocPara *para,int nodeIndex) +{ + //printf("insideStyleChangeThatIsOutputParagraph(index=%d)\n",nodeIndex); + int styleMask=0; + bool styleOutsideParagraph=FALSE; + while (nodeIndex>=0 && !styleOutsideParagraph) + { + DocNode *n = para->children().at(nodeIndex); + if (n->kind()==DocNode::Kind_StyleChange) + { + DocStyleChange *sc = (DocStyleChange*)n; + if (!sc->enable()) // remember styles that has been closed already + { + styleMask|=(int)sc->style(); + } + bool paraStyle = sc->style()==DocStyleChange::Center || + sc->style()==DocStyleChange::Div || + sc->style()==DocStyleChange::Preformatted; + //printf("Found style change %s enabled=%d\n",sc->styleString(),sc->enable()); + if (sc->enable() && (styleMask&(int)sc->style())==0 && // style change that is still active + paraStyle + ) + { + styleOutsideParagraph=TRUE; + } + } + nodeIndex--; + } + return styleOutsideParagraph; +} + /** Used for items found inside a paragraph, which due to XHTML restrictions * have to be outside of the paragraph. This method will forcefully end * the current paragraph and forceStartParagraph() will restart it. @@ -2057,7 +2092,7 @@ void HtmlDocVisitor::forceEndParagraph(DocNode *n) int nodeIndex = para->children().findRef(n); nodeIndex--; if (nodeIndex<0) return; // first node - while (nodeIndex>=0 && + while (nodeIndex>=0 && para->children().at(nodeIndex)->kind()==DocNode::Kind_WhiteSpace ) { @@ -2069,12 +2104,14 @@ void HtmlDocVisitor::forceEndParagraph(DocNode *n) //printf("n=%p kind=%d outside=%d\n",n,n->kind(),mustBeOutsideParagraph(n)); if (mustBeOutsideParagraph(n)) return; } - + nodeIndex--; + bool styleOutsideParagraph=insideStyleChangeThatIsOutsideParagraph(para,nodeIndex); bool isFirst; bool isLast; getParagraphContext(para,isFirst,isLast); - //printf("forceEnd first=%d last=%d\n",isFirst,isLast); + //printf("forceEnd first=%d last=%d styleOutsideParagraph=%d\n",isFirst,isLast,styleOutsideParagraph); if (isFirst && isLast) return; + if (styleOutsideParagraph) return; m_t << "

"; } @@ -2092,9 +2129,11 @@ void HtmlDocVisitor::forceStartParagraph(DocNode *n) DocPara *para = (DocPara*)n->parent(); int nodeIndex = para->children().findRef(n); int numNodes = para->children().count(); + bool styleOutsideParagraph=insideStyleChangeThatIsOutsideParagraph(para,nodeIndex); + if (styleOutsideParagraph) return; nodeIndex++; if (nodeIndex==numNodes) return; // last node - while (nodeIndexchildren().at(nodeIndex)->kind()==DocNode::Kind_WhiteSpace ) { -- cgit v0.12