Skip to content

Commit

Permalink
Bug 746162 - formulas creating invalid HTML code
Browse files Browse the repository at this point in the history
  • Loading branch information
Dimitri van Heesch committed Dec 26, 2015
1 parent de03970 commit d590587
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 11 deletions.
14 changes: 11 additions & 3 deletions src/docparser.h
Expand Up @@ -309,10 +309,18 @@ class DocCite : public DocNode
class DocStyleChange : public DocNode class DocStyleChange : public DocNode
{ {
public: public:
enum Style { Bold, Italic, Code, Center, Small, enum Style { Bold = (1<<0),
Subscript, Superscript, Preformatted, Italic = (1<<1),
Span, Div 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, DocStyleChange(DocNode *parent,uint position,Style s,bool enable,
const HtmlAttribList *attribs=0) : const HtmlAttribList *attribs=0) :
m_position(position), m_style(s), m_enable(enable) m_position(position), m_style(s), m_enable(enable)
Expand Down
55 changes: 47 additions & 8 deletions src/htmldocvisitor.cpp
Expand Up @@ -42,7 +42,7 @@ static const char types[][NUM_HTML_LIST_TYPES] = {"1", "a", "i", "A"};
static QCString convertIndexWordToAnchor(const QString &word) static QCString convertIndexWordToAnchor(const QString &word)
{ {
static char hex[] = "0123456789abcdef"; static char hex[] = "0123456789abcdef";
QCString result; QCString result="a";
const char *str = word.data(); const char *str = word.data();
unsigned char c; unsigned char c;
if (str) if (str)
Expand All @@ -54,16 +54,15 @@ static QCString convertIndexWordToAnchor(const QString &word)
(c >= '0' && c <= '9') || // DIGIT (c >= '0' && c <= '9') || // DIGIT
c == '-' || c == '-' ||
c == '.' || c == '.' ||
c == '_' || c == '_'
c == '~'
) )
{ {
result += c; result += c;
} }
else else
{ {
char enc[4]; char enc[4];
enc[0] = '%'; enc[0] = ':';
enc[1] = hex[(c & 0xf0) >> 4]; enc[1] = hex[(c & 0xf0) >> 4];
enc[2] = hex[c & 0xf]; enc[2] = hex[c & 0xf];
enc[3] = 0; enc[3] = 0;
Expand Down Expand Up @@ -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 /** Used for items found inside a paragraph, which due to XHTML restrictions
* have to be outside of the paragraph. This method will forcefully end * have to be outside of the paragraph. This method will forcefully end
* the current paragraph and forceStartParagraph() will restart it. * the current paragraph and forceStartParagraph() will restart it.
Expand All @@ -2057,7 +2092,7 @@ void HtmlDocVisitor::forceEndParagraph(DocNode *n)
int nodeIndex = para->children().findRef(n); int nodeIndex = para->children().findRef(n);
nodeIndex--; nodeIndex--;
if (nodeIndex<0) return; // first node if (nodeIndex<0) return; // first node
while (nodeIndex>=0 && while (nodeIndex>=0 &&
para->children().at(nodeIndex)->kind()==DocNode::Kind_WhiteSpace para->children().at(nodeIndex)->kind()==DocNode::Kind_WhiteSpace
) )
{ {
Expand All @@ -2069,12 +2104,14 @@ void HtmlDocVisitor::forceEndParagraph(DocNode *n)
//printf("n=%p kind=%d outside=%d\n",n,n->kind(),mustBeOutsideParagraph(n)); //printf("n=%p kind=%d outside=%d\n",n,n->kind(),mustBeOutsideParagraph(n));
if (mustBeOutsideParagraph(n)) return; if (mustBeOutsideParagraph(n)) return;
} }

nodeIndex--;
bool styleOutsideParagraph=insideStyleChangeThatIsOutsideParagraph(para,nodeIndex);
bool isFirst; bool isFirst;
bool isLast; bool isLast;
getParagraphContext(para,isFirst,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 (isFirst && isLast) return;
if (styleOutsideParagraph) return;


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

0 comments on commit d590587

Please sign in to comment.