summaryrefslogtreecommitdiffstats
path: root/src/htmldocvisitor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/htmldocvisitor.cpp')
-rw-r--r--src/htmldocvisitor.cpp176
1 files changed, 138 insertions, 38 deletions
diff --git a/src/htmldocvisitor.cpp b/src/htmldocvisitor.cpp
index 5f0e411..6386cb8 100644
--- a/src/htmldocvisitor.cpp
+++ b/src/htmldocvisitor.cpp
@@ -34,6 +34,7 @@
#include "filedef.h"
#include "memberdef.h"
#include "htmlentity.h"
+#include "emoji.h"
#include "plantuml.h"
static const int NUM_HTML_LIST_TYPES = 4;
@@ -138,6 +139,7 @@ static bool mustBeOutsideParagraph(DocNode *n)
case DocNode::Kind_HtmlBlockQuote:
/* \parblock */
case DocNode::Kind_ParBlock:
+ case DocNode::Kind_IncOperator:
return TRUE;
case DocNode::Kind_Verbatim:
{
@@ -156,7 +158,59 @@ static bool mustBeOutsideParagraph(DocNode *n)
return FALSE;
}
-static QString htmlAttribsToString(const HtmlAttribList &attribs, const bool img_tag = FALSE)
+static bool isDocVerbatimVisible(DocVerbatim *s)
+{
+ switch(s->type())
+ {
+ case DocVerbatim::ManOnly:
+ case DocVerbatim::LatexOnly:
+ case DocVerbatim::XmlOnly:
+ case DocVerbatim::RtfOnly:
+ case DocVerbatim::DocbookOnly:
+ return FALSE;
+ default:
+ return TRUE;
+ }
+}
+
+static bool isDocIncludeVisible(DocInclude *s)
+{
+ switch (s->type())
+ {
+ case DocInclude::DontInclude:
+ case DocInclude::LatexInclude:
+ return FALSE;
+ default:
+ return TRUE;
+ }
+}
+
+static bool isDocIncOperatorVisible(DocIncOperator *s)
+{
+ switch (s->type())
+ {
+ case DocIncOperator::Skip:
+ return FALSE;
+ default:
+ return TRUE;
+ }
+}
+
+static bool isInvisibleNode(DocNode *node)
+{
+ return (node->kind()==DocNode::Kind_WhiteSpace)
+ || // skip over image nodes that are not for HTML output
+ (node->kind()==DocNode::Kind_Image && ((DocImage*)node)->type()!=DocImage::Html)
+ || // skip over verbatim nodes that are not visible in the HTML output
+ (node->kind()==DocNode::Kind_Verbatim && !isDocVerbatimVisible((DocVerbatim*)node))
+ || // skip over include nodes that are not visible in the HTML output
+ (node->kind()==DocNode::Kind_Include && !isDocIncludeVisible((DocInclude*)node))
+ || // skip over include operator nodes that are not visible in the HTML output
+ (node->kind()==DocNode::Kind_IncOperator && !isDocIncOperatorVisible((DocIncOperator*)node))
+ ;
+}
+
+static QString htmlAttribsToString(const HtmlAttribList &attribs, bool img_tag = FALSE)
{
QString result;
HtmlAttribListIterator li(attribs);
@@ -239,6 +293,20 @@ void HtmlDocVisitor::visit(DocSymbol *s)
}
}
+void HtmlDocVisitor::visit(DocEmoji *s)
+{
+ if (m_hide) return;
+ const char *res = EmojiEntityMapper::instance()->unicode(s->index());
+ if (res)
+ {
+ m_t << res;
+ }
+ else
+ {
+ m_t << s->name();
+ }
+}
+
void HtmlDocVisitor::writeObfuscatedMailAddress(const QCString &url)
{
m_t << "<a href=\"#\" onclick=\"location.href='mai'+'lto:'";
@@ -393,7 +461,6 @@ static void visitCaption(HtmlDocVisitor *parent, QList<DocNode> children)
for (cli.toFirst();(n=cli.current());++cli) n->accept(parent);
}
-
void HtmlDocVisitor::visit(DocVerbatim *s)
{
if (m_hide) return;
@@ -433,10 +500,12 @@ void HtmlDocVisitor::visit(DocVerbatim *s)
m_t << "</pre>" /*<< PREFRAG_END*/;
forceStartParagraph(s);
break;
- case DocVerbatim::HtmlOnly:
- if (s->isBlock()) forceEndParagraph(s);
- m_t << s->text();
- if (s->isBlock()) forceStartParagraph(s);
+ case DocVerbatim::HtmlOnly:
+ {
+ if (s->isBlock()) forceEndParagraph(s);
+ m_t << s->text();
+ if (s->isBlock()) forceStartParagraph(s);
+ }
break;
case DocVerbatim::ManOnly:
case DocVerbatim::LatexOnly:
@@ -594,8 +663,12 @@ void HtmlDocVisitor::visit(DocInclude *inc)
break;
case DocInclude::DontInclude:
break;
- case DocInclude::HtmlInclude:
- m_t << inc->text();
+ case DocInclude::HtmlInclude:
+ {
+ if (inc->isBlock()) forceEndParagraph(inc);
+ m_t << inc->text();
+ if (inc->isBlock()) forceStartParagraph(inc);
+ }
break;
case DocInclude::LatexInclude:
break;
@@ -668,7 +741,7 @@ void HtmlDocVisitor::visit(DocIncOperator *op)
// op->type(),op->isFirst(),op->isLast(),op->text().data());
if (op->isFirst())
{
- forceStartParagraph(op);
+ forceEndParagraph(op);
if (!m_hide) m_t << PREFRAG_START;
pushEnabled();
m_hide=TRUE;
@@ -1097,8 +1170,7 @@ void HtmlDocVisitor::visitPre(DocPara *p)
uint nodeIndex = 0;
if (p && nodeIndex<p->children().count())
{
- while (nodeIndex<p->children().count() &&
- p->children().at(nodeIndex)->kind()==DocNode::Kind_WhiteSpace)
+ while (nodeIndex<p->children().count() && isInvisibleNode(p->children().at(nodeIndex)))
{
nodeIndex++;
}
@@ -1166,7 +1238,7 @@ void HtmlDocVisitor::visitPost(DocPara *p)
int nodeIndex = p->children().count()-1;
if (nodeIndex>=0)
{
- while (nodeIndex>=0 && p->children().at(nodeIndex)->kind()==DocNode::Kind_WhiteSpace)
+ while (nodeIndex>=0 && isInvisibleNode(p->children().at(nodeIndex)))
{
nodeIndex--;
}
@@ -1537,7 +1609,22 @@ void HtmlDocVisitor::visitPre(DocImage *img)
{
if (img->type()==DocImage::Html)
{
- forceEndParagraph(img);
+ bool inlineImage = img->isInlineImage();
+ bool typeSVG = FALSE;
+
+ QCString url = img->url();
+ if (url.isEmpty())
+ {
+ typeSVG = (img->name().right(4)==".svg");
+ }
+ else
+ {
+ typeSVG = (url.right(4)==".svg");
+ }
+ if (!inlineImage)
+ {
+ forceEndParagraph(img);
+ }
if (m_hide) return;
QString baseName=img->name();
int i;
@@ -1545,20 +1632,19 @@ void HtmlDocVisitor::visitPre(DocImage *img)
{
baseName=baseName.right(baseName.length()-i-1);
}
- m_t << "<div class=\"image\">" << endl;
- QCString url = img->url();
+ if (!inlineImage) m_t << "<div class=\"image\">" << endl;
QCString sizeAttribs;
if (!img->width().isEmpty())
{
sizeAttribs+=" width=\""+img->width()+"\"";
}
- if (!img->height().isEmpty())
+ if (!img->height().isEmpty()) // link to local file
{
sizeAttribs+=" height=\""+img->height()+"\"";
}
if (url.isEmpty())
{
- if (img->name().right(4)==".svg")
+ if (typeSVG)
{
m_t << "<object type=\"image/svg+xml\" data=\"" << img->relPath() << img->name()
<< "\"" << sizeAttribs << htmlAttribsToString(img->attribs()) << ">" << baseName
@@ -1568,27 +1654,39 @@ void HtmlDocVisitor::visitPre(DocImage *img)
{
m_t << "<img src=\"" << img->relPath() << img->name() << "\" alt=\""
<< baseName << "\"" << sizeAttribs << htmlAttribsToString(img->attribs())
- << "/>" << endl;
+ << (inlineImage ? " class=\"inline\"" : "/>\n");
}
}
- else
+ else // link to URL
{
- if (url.right(4)==".svg")
+ if (typeSVG)
{
m_t << "<object type=\"image/svg+xml\" data=\"" << correctURL(url,img->relPath())
- << "\"" << sizeAttribs << htmlAttribsToString(img->attribs()) << "></object>" << endl;
+ << "\"" << sizeAttribs << htmlAttribsToString(img->attribs())
+ << "></object>" << endl;
}
else
{
m_t << "<img src=\"" << correctURL(url,img->relPath()) << "\""
<< sizeAttribs << htmlAttribsToString(img->attribs(), TRUE)
- << "/>" << endl;
+ << (inlineImage ? " class=\"inline\"" : "/>\n");
}
}
if (img->hasCaption())
{
- m_t << "<div class=\"caption\">" << endl;
- m_t << getHtmlDirEmbedingChar(getTextDirByConfig(img));
+ if (inlineImage)
+ {
+ m_t << " title=\"";
+ }
+ else
+ {
+ m_t << "<div class=\"caption\">" << endl;
+ m_t << getHtmlDirEmbedingChar(getTextDirByConfig(img));
+ }
+ }
+ else if (inlineImage)
+ {
+ m_t << "/>" << endl;
}
}
else // other format -> skip
@@ -1598,17 +1696,24 @@ void HtmlDocVisitor::visitPre(DocImage *img)
}
}
-void HtmlDocVisitor::visitPost(DocImage *img)
+void HtmlDocVisitor::visitPost(DocImage *img)
{
if (img->type()==DocImage::Html)
{
if (m_hide) return;
+ bool inlineImage = img->isInlineImage();
if (img->hasCaption())
{
- m_t << "</div>";
+ if (inlineImage)
+ m_t << "\"/>\n ";
+ else
+ m_t << "</div>";
+ }
+ if (!inlineImage)
+ {
+ m_t << "</div>" << endl;
+ forceStartParagraph(img);
}
- m_t << "</div>" << endl;
- forceStartParagraph(img);
}
else // other format
{
@@ -2236,16 +2341,13 @@ void HtmlDocVisitor::forceEndParagraph(DocNode *n)
int nodeIndex = para->children().findRef(n);
nodeIndex--;
if (nodeIndex<0) return; // first node
- while (nodeIndex>=0 &&
- para->children().at(nodeIndex)->kind()==DocNode::Kind_WhiteSpace
- )
+ while (nodeIndex>=0 && isInvisibleNode(para->children().at(nodeIndex)))
{
- nodeIndex--;
+ nodeIndex--;
}
if (nodeIndex>=0)
{
DocNode *n = para->children().at(nodeIndex);
- //printf("n=%p kind=%d outside=%d\n",n,n->kind(),mustBeOutsideParagraph(n));
if (mustBeOutsideParagraph(n)) return;
}
nodeIndex--;
@@ -2277,16 +2379,14 @@ void HtmlDocVisitor::forceStartParagraph(DocNode *n)
if (styleOutsideParagraph) return;
nodeIndex++;
if (nodeIndex==numNodes) return; // last node
- while (nodeIndex<numNodes &&
- para->children().at(nodeIndex)->kind()==DocNode::Kind_WhiteSpace
- )
+ while (nodeIndex<numNodes && isInvisibleNode(para->children().at(nodeIndex)))
{
nodeIndex++;
}
if (nodeIndex<numNodes)
{
DocNode *n = para->children().at(nodeIndex);
- if (mustBeOutsideParagraph(n)) return;
+ if (mustBeOutsideParagraph(n)) return; // next element also outside paragraph
}
else
{
@@ -2297,8 +2397,8 @@ void HtmlDocVisitor::forceStartParagraph(DocNode *n)
bool isFirst;
bool isLast;
getParagraphContext(para,isFirst,isLast);
- //printf("forceStart first=%d last=%d\n",isFirst,isLast);
if (isFirst && isLast) needsTag = FALSE;
+ //printf("forceStart first=%d last=%d needsTag=%d\n",isFirst,isLast,needsTag);
if (needsTag)
m_t << "<p" << getDirHtmlClassOfNode(getTextDirByConfig(para, nodeIndex)) << ">";