From 4682b91364247aafe66b6af472e321511e115e7c Mon Sep 17 00:00:00 2001 From: albert-github Date: Thu, 9 Aug 2018 19:49:58 +0200 Subject: Inline images Create the possibility of inline images with the `\image` command by means of the option `inline`. --- doc/commands.doc | 6 ++++- src/docbookvisitor.cpp | 10 ++++---- src/docparser.cpp | 47 +++++++++++++++++++++++++++++++---- src/docparser.h | 4 ++- src/htmldocvisitor.cpp | 60 +++++++++++++++++++++++++++++++++++++-------- src/latexdocvisitor.cpp | 59 ++++++++++++++++++++++++++++++++------------ src/printdocvisitor.h | 2 +- src/rtfdocvisitor.cpp | 55 +++++++++++++++++++++++++++-------------- src/rtfdocvisitor.h | 4 +-- src/xmldocvisitor.cpp | 5 ++-- templates/html/doxygen.css | 2 +- templates/latex/doxygen.sty | 6 +++++ 12 files changed, 198 insertions(+), 62 deletions(-) diff --git a/doc/commands.doc b/doc/commands.doc index 6c680ee..a9973ce 100644 --- a/doc/commands.doc +++ b/doc/commands.doc @@ -3052,7 +3052,7 @@ class Receiver \ref cmddocbookonly "\\docbookonly".
-\section cmdimage \\image ["caption"] [=] +\section cmdimage \\image['{'[option]'}'] ["caption"] [=] \addindex \\image Inserts an image into the documentation. This command is format @@ -3084,6 +3084,10 @@ class Receiver The size specifier in \LaTeX (for example `10cm` or `4in` or a symbolic width like `\\textwidth`). + Currently only the option `inline` is supported. In case the option `inline` is + specified the image is placed "in the line", when a caption s present it is shown + in HTML as tooltip (ignored for the other formats). + Here is example of a comment block: \verbatim diff --git a/src/docbookvisitor.cpp b/src/docbookvisitor.cpp index ab10da0..78d19a4 100644 --- a/src/docbookvisitor.cpp +++ b/src/docbookvisitor.cpp @@ -36,7 +36,7 @@ #include "htmlentity.h" #include "plantuml.h" -static void visitPreStart(FTextStream &t, const bool hasCaption, QCString name, QCString width, QCString height) +static void visitPreStart(FTextStream &t, const bool hasCaption, QCString name, QCString width, QCString height, const bool inlineImage = FALSE) { QCString tmpStr; t << "
" << endl; @@ -50,7 +50,7 @@ static void visitPreStart(FTextStream &t, const bool hasCaption, QCString name, } else { - t << " width=\"50%\""; + if (!inlineImage) t << " width=\"50%\""; } if (!height.isEmpty()) { @@ -65,7 +65,7 @@ static void visitPreStart(FTextStream &t, const bool hasCaption, QCString name, } } -static void visitPostEnd(FTextStream &t, const bool hasCaption) +static void visitPostEnd(FTextStream &t, const bool hasCaption, const bool inlineImage = FALSE) { t << endl; if (hasCaption) @@ -910,7 +910,7 @@ void DocbookDocVisitor::visitPre(DocImage *img) { baseName=baseName.right(baseName.length()-i-1); } - visitPreStart(m_t, img -> hasCaption(), baseName, img -> width(), img -> height()); + visitPreStart(m_t, img -> hasCaption(), baseName, img -> width(), img -> height(),img -> isInlineImage()); } else { @@ -924,7 +924,7 @@ void DocbookDocVisitor::visitPost(DocImage *img) if (img->type()==DocImage::DocBook) { if (m_hide) return; - visitPostEnd(m_t, img -> hasCaption()); + visitPostEnd(m_t, img -> hasCaption(),img -> isInlineImage()); // copy the image to the output dir QCString baseName=img->name(); int i; diff --git a/src/docparser.cpp b/src/docparser.cpp index 7e050b3..4cf7c4e 100644 --- a/src/docparser.cpp +++ b/src/docparser.cpp @@ -2962,10 +2962,10 @@ void DocVhdlFlow::parse() //--------------------------------------------------------------------------- DocImage::DocImage(DocNode *parent,const HtmlAttribList &attribs,const QCString &name, - Type t,const QCString &url) : + Type t,const QCString &url, const 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; } @@ -5065,13 +5065,50 @@ 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", + 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; + return; + } } tok=doctokenizerYYlex(); if (tok!=TK_WORD && tok!=TK_LNKWORD) @@ -5110,7 +5147,7 @@ void DocPara::handleImage(const QCString &cmdName) 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(); } diff --git a/src/docparser.h b/src/docparser.h index d7390c2..69259d6 100644 --- a/src/docparser.h +++ b/src/docparser.h @@ -737,7 +737,7 @@ class DocImage : public CompAccept public: enum Type { Html, Latex, Rtf, DocBook }; DocImage(DocNode *parent,const HtmlAttribList &attribs, - const QCString &name,Type t,const QCString &url=QCString()); + const QCString &name,Type t,const QCString &url=QCString(), const bool inlineImage = TRUE); Kind kind() const { return Kind_Image; } Type type() const { return m_type; } QCString name() const { return m_name; } @@ -746,6 +746,7 @@ class DocImage : public CompAccept QCString height() const { return m_height; } QCString relPath() const { return m_relPath; } QCString url() const { return m_url; } + bool isInlineImage() const { return m_inlineImage; } const HtmlAttribList &attribs() const { return m_attribs; } void parse(); @@ -757,6 +758,7 @@ class DocImage : public CompAccept QCString m_height; QCString m_relPath; QCString m_url; + bool m_inlineImage; }; /** Node representing a dot file */ diff --git a/src/htmldocvisitor.cpp b/src/htmldocvisitor.cpp index 6a9c142..6bd5347 100644 --- a/src/htmldocvisitor.cpp +++ b/src/htmldocvisitor.cpp @@ -1485,7 +1485,19 @@ 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 && !typeSVG) forceEndParagraph(img); if (m_hide) return; QString baseName=img->name(); int i; @@ -1493,8 +1505,7 @@ void HtmlDocVisitor::visitPre(DocImage *img) { baseName=baseName.right(baseName.length()-i-1); } - m_t << "
" << endl; - QCString url = img->url(); + if (!inlineImage && !typeSVG) m_t << "
" << endl; QCString sizeAttribs; if (!img->width().isEmpty()) { @@ -1516,7 +1527,7 @@ void HtmlDocVisitor::visitPre(DocImage *img) { m_t << "relPath() << img->name() << "\" alt=\"" << baseName << "\"" << sizeAttribs << htmlAttribsToString(img->attribs()) - << "/>" << endl; + << (inlineImage ? " class=\"inline\"" : "/>\n"); } } else @@ -1530,13 +1541,24 @@ void HtmlDocVisitor::visitPre(DocImage *img) { m_t << "relPath()) << "\"" << sizeAttribs << htmlAttribsToString(img->attribs(), TRUE) - << "/>" << endl; + << (inlineImage ? " class=\"inline\"" : "/>\n"); } } if (img->hasCaption()) { - m_t << "
" << endl; - m_t << getHtmlDirEmbedingChar(getTextDirByConfig(img)); + if (inlineImage) + { + m_t << " title=\""; + } + else + { + m_t << "
" << endl; + m_t << getHtmlDirEmbedingChar(getTextDirByConfig(img)); + } + } + else if (inlineImage) + { + m_t << "/>" << endl; } } else // other format -> skip @@ -1551,12 +1573,30 @@ void HtmlDocVisitor::visitPost(DocImage *img) if (img->type()==DocImage::Html) { if (m_hide) return; + 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 && img->hasCaption()) if (img->hasCaption()) { - m_t << "
"; + if (inlineImage) + m_t << "\"/>\n "; + else + m_t << "
"; + } + if (!inlineImage && !typeSVG) + { + m_t << "
" << endl; + forceStartParagraph(img); } - m_t << "
" << endl; - forceStartParagraph(img); } else // other format { diff --git a/src/latexdocvisitor.cpp b/src/latexdocvisitor.cpp index d2c4c5d..03f9872 100644 --- a/src/latexdocvisitor.cpp +++ b/src/latexdocvisitor.cpp @@ -48,16 +48,23 @@ static const char *getSectionName(int level) return secLabels[QMIN(maxLevels-1,l)]; } -static void visitPreStart(FTextStream &t, const bool hasCaption, QCString name, QCString width, QCString height) +static void visitPreStart(FTextStream &t, const bool hasCaption, QCString name, QCString width, QCString height, const bool inlineImage = FALSE) { - if (hasCaption) + if (inlineImage) { - t << "\n\\begin{DoxyImage}\n"; + t << "\n\\begin{DoxyInlineImage}\n"; } else { - t << "\n\\begin{DoxyImageNoCaption}\n" - " \\mbox{"; + if (hasCaption) + { + t << "\n\\begin{DoxyImage}\n"; + } + else + { + t << "\n\\begin{DoxyImageNoCaption}\n" + " \\mbox{"; + } } t << "\\includegraphics"; @@ -80,7 +87,14 @@ static void visitPreStart(FTextStream &t, const bool hasCaption, QCString name, if (width.isEmpty() && height.isEmpty()) { /* default setting */ - t << "[width=\\textwidth,height=\\textheight/2,keepaspectratio=true]"; + if (inlineImage) + { + t << "[height=\\baselineskip,keepaspectratio=true]"; + } + else + { + t << "[width=\\textwidth,height=\\textheight/2,keepaspectratio=true]"; + } } else { @@ -91,21 +105,36 @@ static void visitPreStart(FTextStream &t, const bool hasCaption, QCString name, if (hasCaption) { - t << "\n\\doxyfigcaption{"; + if (!inlineImage) + { + t << "\n\\doxyfigcaption{"; + } + else + { + t << "%"; // to catch the caption + } } } -static void visitPostEnd(FTextStream &t, const bool hasCaption) +static void visitPostEnd(FTextStream &t, const bool hasCaption, const bool inlineImage = FALSE) { - t << "}\n"; // end mbox or caption - if (hasCaption) + if (inlineImage) { - t << "\\end{DoxyImage}\n"; + t << "\n\\end{DoxyInlineImage}\n"; } - else{ - t << "\\end{DoxyImageNoCaption}\n"; + else + { + t << "}\n"; // end mbox or caption + if (hasCaption) + { + t << "\\end{DoxyImage}\n"; + } + else + { + t << "\\end{DoxyImageNoCaption}\n"; + } } } @@ -1280,7 +1309,7 @@ void LatexDocVisitor::visitPre(DocImage *img) gfxName=gfxName.left(gfxName.length()-4); } - visitPreStart(m_t,img->hasCaption(), gfxName, img->width(), img->height()); + visitPreStart(m_t,img->hasCaption(), gfxName, img->width(), img->height(), img->isInlineImage()); } else // other format -> skip { @@ -1294,7 +1323,7 @@ void LatexDocVisitor::visitPost(DocImage *img) if (img->type()==DocImage::Latex) { if (m_hide) return; - visitPostEnd(m_t,img->hasCaption()); + visitPostEnd(m_t,img->hasCaption(), img->isInlineImage()); } else // other format { diff --git a/src/printdocvisitor.h b/src/printdocvisitor.h index d1dbb74..4d1d765 100644 --- a/src/printdocvisitor.h +++ b/src/printdocvisitor.h @@ -490,7 +490,7 @@ class PrintDocVisitor : public DocVisitor case DocImage::Rtf: printf("rtf"); break; case DocImage::DocBook: printf("docbook"); break; } - printf("\" %s %s>\n",img->width().data(),img->height().data()); + printf("\" %s %s inline=\"%s\">\n",img->width().data(),img->height().data(),img->isInlineImage() ? "yes" : "no"); } void visitPost(DocImage *) { diff --git a/src/rtfdocvisitor.cpp b/src/rtfdocvisitor.cpp index ec6d015..fa7fb64 100644 --- a/src/rtfdocvisitor.cpp +++ b/src/rtfdocvisitor.cpp @@ -1088,27 +1088,37 @@ void RTFDocVisitor::visitPost(DocHtmlHeader *) void RTFDocVisitor::visitPre(DocImage *img) { DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocImage)}\n"); - includePicturePreRTF(img->name(), img->type()==DocImage::Rtf, img->hasCaption()); + includePicturePreRTF(img->name(), img->type()==DocImage::Rtf, img->hasCaption(), img->isInlineImage()); } - -void RTFDocVisitor::includePicturePreRTF(const QCString name, const bool isTypeRTF, const bool hasCaption) +void RTFDocVisitor::includePicturePreRTF(const QCString name, const bool isTypeRTF, const bool hasCaption, const bool inlineImage) { if (isTypeRTF) { - m_t << "\\par" << endl; - m_t << "{" << endl; - m_t << rtf_Style_Reset << endl; - if (hasCaption || m_lastIsPara) m_t << "\\par" << endl; - m_t << "\\pard \\qc { \\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \""; + if (!inlineImage) + { + m_t << "\\par" << endl; + m_t << "{" << endl; + m_t << rtf_Style_Reset << endl; + if (hasCaption || m_lastIsPara) m_t << "\\par" << endl; + m_t << "\\pard \\qc "; + } + m_t << "{ \\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \""; m_t << name; m_t << "\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt Image}}" << endl; - m_t << "\\par" << endl; - if (hasCaption) + if (!inlineImage) + { + m_t << "\\par" << endl; + if (hasCaption) + { + m_t << "\\pard \\qc \\b"; + m_t << "{Image \\field\\flddirty{\\*\\fldinst { SEQ Image \\\\*Arabic }}{\\fldrslt {\\noproof 1}} "; + } + m_lastIsPara=TRUE; + } + else { - m_t << "\\pard \\qc \\b"; - m_t << "{Image \\field\\flddirty{\\*\\fldinst { SEQ Image \\\\*Arabic }}{\\fldrslt {\\noproof 1}} "; + if (hasCaption) m_t << "{\\comment "; // to prevent caption to be shown } - m_lastIsPara=TRUE; } else // other format -> skip { @@ -1120,22 +1130,29 @@ void RTFDocVisitor::includePicturePreRTF(const QCString name, const bool isTypeR void RTFDocVisitor::visitPost(DocImage *img) { DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocImage)}\n"); - includePicturePostRTF(img->type()==DocImage::Rtf, img->hasCaption()); + includePicturePostRTF(img->type()==DocImage::Rtf, img->hasCaption(), img->isInlineImage()); } -void RTFDocVisitor::includePicturePostRTF(const bool isTypeRTF, const bool hasCaption) +void RTFDocVisitor::includePicturePostRTF(const bool isTypeRTF, const bool hasCaption, const bool inlineImage) { if (isTypeRTF) { if (m_hide) return; - if (hasCaption) + if (inlineImage) { - m_t << "}" < children) static void visitPreStart(FTextStream &t, const char *cmd, const bool doCaption, XmlDocVisitor *parent, QList children, const QCString &name, bool writeType, DocImage::Type type, const QCString &width, - const QCString &height) + const QCString &height, const bool inlineImage = FALSE) { t << "<" << cmd; if (writeType) @@ -69,6 +69,7 @@ static void visitPreStart(FTextStream &t, const char *cmd, const bool doCaption, { t << " height=\"" << convertToXML(height) << "\""; } + if (inlineImage) t << " inline=\"yes\">"; if (doCaption) { t << " caption=\""; @@ -767,7 +768,7 @@ void XmlDocVisitor::visitPre(DocImage *img) { baseName=baseName.right(baseName.length()-i-1); } - visitPreStart(m_t, "image", FALSE, this, img->children(), baseName, TRUE, img->type(), img->width(), img->height()); + visitPreStart(m_t, "image", FALSE, this, img->children(), baseName, TRUE, img->type(), img->width(), img->height(), img ->isInlineImage()); // copy the image to the output dir FileDef *fd; diff --git a/templates/html/doxygen.css b/templates/html/doxygen.css index 8e87381..4b4c8ea 100644 --- a/templates/html/doxygen.css +++ b/templates/html/doxygen.css @@ -343,7 +343,7 @@ img.formulaDsp { } -img.formulaInl { +img.formulaInl, img.inline { vertical-align: middle; } diff --git a/templates/latex/doxygen.sty b/templates/latex/doxygen.sty index 7798d48..d0d255c 100644 --- a/templates/latex/doxygen.sty +++ b/templates/latex/doxygen.sty @@ -190,6 +190,12 @@ \end{center}% } +% Used by @image +% (only if inline is specified) +\newenvironment{DoxyInlineImage}{% +}{% +} + % Used by @attention \newenvironment{DoxyAttention}[1]{% \begin{DoxyDesc}{#1}% -- cgit v0.12