Commit 3b9f4d9c authored by Dimitri van Heesch's avatar Dimitri van Heesch

Added @parblock and @endparblock commands

parent b4e5125a
......@@ -85,6 +85,7 @@ documentation:
\refitem cmdendlink \\endlink
\refitem cmdendmanonly \\endmanonly
\refitem cmdendmsc \\endmsc
\refitem cmdendparblock \\endparblock
\refitem cmdendrtfonly \\endrtfonly
\refitem cmdendsecreflist \\endsecreflist
\refitem cmdendverbatim \\endverbatim
......@@ -136,6 +137,7 @@ documentation:
\refitem cmdpar \\par
\refitem cmdparagraph \\paragraph
\refitem cmdparam \\param
\refitem cmdparblock \\parblock
\refitem cmdpost \\post
\refitem cmdpre \\pre
\refitem cmdprivate \\private
......@@ -1472,6 +1474,35 @@ void setPosition(double x,double y,double z,double t)
@param datatype1|datatype2 $paramname description
\endverbatim
<hr>
\section cmdparblock \\parblock
\addindex \\parblock
For commands that expect a single paragraph as argument
(such as \ref cmdpar "\\par", \ref cmdparam "\\param" and \ref cmdwarning "\\warning"),
the \ref cmdparblock "\\parblock" command allows to start a
description that covers multiple paragraphs, which then ends with
\ref cmdendparblock "\\endparblock".
Example:
\verbatim
/** Example of a param command with a description consisting of two paragraphs
* \param p
* \parblock
* First paragraph of the param description.
*
* Second paragraph of the param description.
* \endparblock
* Rest of the comment block continues.
*/
\endverbatim
Note that the \\parblock command may also appear directly after
\\param's first argument.
<hr>
\section cmdendparblock \\endparblock
\addindex \\endparblock
This ends a block of paragraphs started with \\ref cmdparblock "\\parblock".
<hr>
\section cmdtparam \\tparam <template-parameter-name> { description }
......
......@@ -132,6 +132,8 @@ CommandMap cmdMap[] =
{ "docbookonly", CMD_DBONLY },
{ "enddocbookonly",CMD_ENDDBONLY },
{ "endinternal", CMD_ENDINTERNAL },
{ "parblock", CMD_PARBLOCK },
{ "endparblock", CMD_ENDPARBLOCK },
{ 0, 0 },
};
......
......@@ -121,7 +121,9 @@ enum CommandType
CMD_VHDLFLOW = 91,
CMD_DBONLY = 92,
CMD_ENDDBONLY = 93,
CMD_ENDINTERNAL = 94
CMD_ENDINTERNAL = 94,
CMD_PARBLOCK = 95,
CMD_ENDPARBLOCK = 96
};
enum HtmlTagType
......
......@@ -118,6 +118,8 @@ static bool handleExtends(const QCString &);
static bool handleCopyDoc(const QCString &);
static bool handleCopyBrief(const QCString &);
static bool handleCopyDetails(const QCString &);
static bool handleParBlock(const QCString &);
static bool handleEndParBlock(const QCString &);
typedef bool (*DocCmdFunc)(const QCString &name);
......@@ -170,6 +172,8 @@ static DocCmdMap docCmdMap[] =
{ "relates", &handleRelated, TRUE },
{ "relatedalso", &handleRelatedAlso, TRUE },
{ "relatesalso", &handleRelatedAlso, TRUE },
{ "parblock", &handleParBlock, TRUE },
{ "endparblock", &handleEndParBlock, TRUE },
{ "refitem", &handleRefItem, TRUE },
{ "cite", &handleCite, FALSE },
{ "subpage", &handleSubpage, TRUE },
......@@ -421,6 +425,8 @@ static QCString g_copyDocArg;
static QCString g_guardExpr;
static int g_roundCount;
static bool g_insideParBlock;
//-----------------------------------------------------------------------------
static QStack<Grouping> g_autoGroupStack;
......@@ -437,6 +443,7 @@ static void initParser()
g_sectionLabel.resize(0);
g_sectionTitle.resize(0);
g_memberGroupHeader.resize(0);
g_insideParBlock = FALSE;
}
//-----------------------------------------------------------------------------
......@@ -1040,7 +1047,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$"
int i=0;
while (yytext[i]==' ' || yytext[i]=='\t') i++;
g_spaceBeforeCmd = QCString(yytext).left(i);
if (cmdPtr->endsBrief)
if (cmdPtr->endsBrief && inContext!=OutputXRef)
{
briefEndsAtDot=FALSE;
// this command forces the end of brief description
......@@ -1192,7 +1199,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$"
if (inContext==OutputXRef)
{
// see bug 613024, we need to put the newlines after ending the XRef section.
setOutput(OutputDoc);
if (!g_insideParBlock) setOutput(OutputDoc);
int i;
for (i=0;i<yyleng;)
{
......@@ -2389,6 +2396,31 @@ static bool handleXRefItem(const QCString &)
return FALSE;
}
static bool handleParBlock(const QCString &)
{
if (g_insideParBlock)
{
warn(yyFileName,yyLineNr,
"found \\parblock command while already in a parblock!");
}
addOutput("@parblock");
g_insideParBlock = TRUE;
return FALSE;
}
static bool handleEndParBlock(const QCString &)
{
if (!g_insideParBlock)
{
warn(yyFileName,yyLineNr,
"found \\endparblock command without matching \\parblock!");
}
addOutput("@endparblock");
setOutput(OutputDoc); // to end a parblock inside a xrefitem like context
g_insideParBlock = FALSE;
return FALSE;
}
static bool handleRelated(const QCString &)
{
BEGIN(RelatesParam1);
......@@ -2810,6 +2842,12 @@ bool parseCommentBlock(/* in */ ParserInterface *parser,
warn(yyFileName,yyLineNr,"Documentation block ended in the middle of a conditional section!");
}
if (g_insideParBlock)
{
warn(yyFileName,yyLineNr,
"Documentation block ended while inside a \\parblock. Missing \\endparblock");
}
current->doc=stripLeadingAndTrailingEmptyLines(current->doc,current->docLine);
if (current->section==Entry::FILEDOC_SEC && current->doc.isEmpty())
......
......@@ -508,6 +508,7 @@
<xsd:element name="xrefsect" type="docXRefSectType" />
<xsd:element name="copydoc" type="docCopyType" />
<xsd:element name="blockquote" type="docBlockQuoteType" />
<xsd:element name="parblock" type="docParBlockType" />
</xsd:choice>
</xsd:group>
......@@ -707,6 +708,12 @@
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="docParBlockType">
<xsd:sequence>
<xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="docCharType">
<xsd:attribute name="char" type="DoxCharRange"/>
</xsd:complexType>
......
......@@ -508,6 +508,7 @@
" <xsd:element name=\"xrefsect\" type=\"docXRefSectType\" />\n"
" <xsd:element name=\"copydoc\" type=\"docCopyType\" />\n"
" <xsd:element name=\"blockquote\" type=\"docBlockQuoteType\" />\n"
" <xsd:element name=\"parblock\" type=\"docParBlockType\" />\n"
" </xsd:choice>\n"
" </xsd:group>\n"
"\n"
......@@ -707,6 +708,12 @@
" </xsd:sequence>\n"
" </xsd:complexType>\n"
"\n"
" <xsd:complexType name=\"docParBlockType\">\n"
" <xsd:sequence>\n"
" <xsd:element name=\"para\" type=\"docParaType\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n"
" </xsd:sequence>\n"
" </xsd:complexType>\n"
"\n"
" <xsd:complexType name=\"docCharType\">\n"
" <xsd:attribute name=\"char\" type=\"DoxCharRange\"/> \n"
" </xsd:complexType>\n"
......
......@@ -1223,6 +1223,15 @@ void DocbookDocVisitor::visitPost(DocVhdlFlow *)
// TODO: to be implemented
}
void DocbookDocVisitor::visitPre(DocParBlock *)
{
}
void DocbookDocVisitor::visitPost(DocParBlock *)
{
}
void DocbookDocVisitor::filter(const char *str)
{
m_t << convertToXML(str);
......
......@@ -129,6 +129,9 @@ class DocbookDocVisitor : public DocVisitor
void visitPost(DocHtmlBlockQuote *);
void visitPre(DocVhdlFlow *);
void visitPost(DocVhdlFlow *);
void visitPre(DocParBlock *);
void visitPost(DocParBlock *);
private:
//--------------------------------------
// helper functions
......
......@@ -1562,6 +1562,7 @@ DocSymbol::SymType DocSymbol::decodeSymbol(const QCString &symName,char *letter)
{
int l=symName.length();
DBG(("decodeSymbol(%s) l=%d\n",qPrint(symName),l));
// TODO: replace this with a hash
if (symName=="&copy;") return DocSymbol::Copy;
else if (symName=="&trade;") return DocSymbol::Tm;
else if (symName=="&tm;") return DocSymbol::Tm; // alias for &trade;
......@@ -4323,6 +4324,33 @@ int DocHtmlBlockQuote::parse()
//---------------------------------------------------------------------------
int DocParBlock::parse()
{
DBG(("DocParBlock::parse() start\n"));
int retval=0;
g_nodeStack.push(this);
// parse one or more paragraphs
bool isFirst=TRUE;
DocPara *par=0;
do
{
par = new DocPara(this);
if (isFirst) { par->markFirst(); isFirst=FALSE; }
m_children.append(par);
retval=par->parse();
}
while (retval==TK_NEWPARA);
if (par) par->markLast();
DocNode *n=g_nodeStack.pop();
ASSERT(n==this);
DBG(("DocParBlock::parse() end retval=%x\n",retval));
return (retval==RetVal_EndBlockQuote) ? RetVal_OK : retval;
}
//---------------------------------------------------------------------------
int DocSimpleListItem::parse()
{
g_nodeStack.push(this);
......@@ -5509,6 +5537,9 @@ int DocPara::handleCommand(const QCString &cmdName)
doctokenizerYYsetStatePara();
}
break;
case CMD_ENDPARBLOCK:
retval=RetVal_EndParBlock;
break;
case CMD_ENDCODE:
case CMD_ENDHTMLONLY:
case CMD_ENDMANONLY:
......@@ -5567,6 +5598,13 @@ int DocPara::handleCommand(const QCString &cmdName)
case CMD_ENDINTERNAL:
retval = RetVal_EndInternal;
break;
case CMD_PARBLOCK:
{
DocParBlock *block = new DocParBlock(this);
m_children.append(block);
retval = block->parse();
}
break;
case CMD_COPYDOC: // fall through
case CMD_COPYBRIEF: // fall through
case CMD_COPYDETAILS:
......
......@@ -130,7 +130,8 @@ class DocNode
Kind_Text = 47,
Kind_MscFile = 48,
Kind_HtmlBlockQuote = 49,
Kind_VhdlFlow = 50
Kind_VhdlFlow = 50,
Kind_ParBlock = 51
};
/*! Creates a new node */
DocNode() : m_parent(0), m_insidePre(FALSE) {}
......@@ -900,6 +901,19 @@ class DocInternal : public CompAccept<DocInternal>, public DocNode
private:
};
/** Node representing an block of paragraphs */
class DocParBlock : public CompAccept<DocParBlock>, public DocNode
{
public:
DocParBlock(DocNode *parent) { m_parent = parent; }
int parse();
Kind kind() const { return Kind_ParBlock; }
void accept(DocVisitor *v) { CompAccept<DocParBlock>::accept(this,v); }
private:
};
/** Node representing a simple list */
class DocSimpleList : public CompAccept<DocSimpleList>, public DocNode
{
......
......@@ -63,7 +63,8 @@ enum Tokens
RetVal_CloseXml = 0x10013,
RetVal_EndBlockQuote = 0x10014,
RetVal_CopyDoc = 0x10015,
RetVal_EndInternal = 0x10016
RetVal_EndInternal = 0x10016,
RetVal_EndParBlock = 0x10017
};
/** @brief Data associated with a token used by the comment block parser. */
......
......@@ -82,6 +82,7 @@ class DocText;
class DocSimpleSectSep;
class DocHtmlBlockQuote;
class DocVhdlFlow;
class DocParBlock;
/*! @brief Abstract visitor that participates in the visitor pattern.
*/
......@@ -189,6 +190,8 @@ class DocVisitor
virtual void visitPost(DocHtmlBlockQuote *) = 0;
virtual void visitPre(DocVhdlFlow *) = 0;
virtual void visitPost(DocVhdlFlow *) = 0;
virtual void visitPre(DocParBlock *) = 0;
virtual void visitPost(DocParBlock *) = 0;
/*! @} */
};
......
......@@ -56,10 +56,14 @@ div.multicol {
-webkit-column-count: 3;
}
p.startli, p.startdd, p.starttd {
p.startli, p.startdd {
margin-top: 2px;
}
p.starttd {
margin-top: 0px;
}
p.endli {
margin-bottom: 0px;
}
......
......@@ -56,10 +56,14 @@
" -webkit-column-count: 3;\n"
"}\n"
"\n"
"p.startli, p.startdd, p.starttd {\n"
"p.startli, p.startdd {\n"
" margin-top: 2px;\n"
"}\n"
"\n"
"p.starttd {\n"
" margin-top: 0px;\n"
"}\n"
"\n"
"p.endli {\n"
" margin-bottom: 0px;\n"
"}\n"
......
......@@ -102,6 +102,8 @@ static bool mustBeOutsideParagraph(DocNode *n)
case DocNode::Kind_Copy:
/* <blockquote> */
case DocNode::Kind_HtmlBlockQuote:
/* \parblock */
case DocNode::Kind_ParBlock:
return TRUE;
case DocNode::Kind_StyleChange:
return ((DocStyleChange*)n)->style()==DocStyleChange::Preformatted ||
......@@ -829,21 +831,21 @@ bool isSeparatedParagraph(DocSimpleSect *parent,DocPara *par)
int i = nodes.findRef(par);
if (i==-1) return FALSE;
int count = parent->children().count();
if (count>1 && i==0)
if (count>1 && i==0) // first node
{
if (nodes.at(i+1)->kind()==DocNode::Kind_SimpleSectSep)
{
return TRUE;
}
}
else if (count>1 && i==count-1)
else if (count>1 && i==count-1) // last node
{
if (nodes.at(i-1)->kind()==DocNode::Kind_SimpleSectSep)
{
return TRUE;
}
}
else if (count>2 && i>0 && i<count-1)
else if (count>2 && i>0 && i<count-1) // intermediate node
{
if (nodes.at(i-1)->kind()==DocNode::Kind_SimpleSectSep &&
nodes.at(i+1)->kind()==DocNode::Kind_SimpleSectSep)
......@@ -863,9 +865,58 @@ static int getParagraphContext(DocPara *p,bool &isFirst,bool &isLast)
{
switch (p->parent()->kind())
{
case DocNode::Kind_ParBlock:
{ // hierarchy: node N -> para -> parblock -> para
// adapt return value to kind of N
DocNode::Kind kind = DocNode::Kind_Para;
if ( p->parent()->parent() && p->parent()->parent()->parent() )
{
kind = p->parent()->parent()->parent()->kind();
}
isFirst=isFirstChildNode((DocParBlock*)p->parent(),p);
isLast =isLastChildNode ((DocParBlock*)p->parent(),p);
t=0;
if (isFirst)
{
if (kind==DocNode::Kind_HtmlListItem ||
kind==DocNode::Kind_SecRefItem)
{
t=1;
}
else if (kind==DocNode::Kind_HtmlDescData ||
kind==DocNode::Kind_XRefItem ||
kind==DocNode::Kind_SimpleSect)
{
t=2;
}
else if (kind==DocNode::Kind_HtmlCell ||
kind==DocNode::Kind_ParamList)
{
t=5;
}
}
if (isLast)
{
if (kind==DocNode::Kind_HtmlListItem ||
kind==DocNode::Kind_SecRefItem)
{
t=3;
}
else if (kind==DocNode::Kind_HtmlDescData ||
kind==DocNode::Kind_XRefItem ||
kind==DocNode::Kind_SimpleSect)
{
t=4;
}
else if (kind==DocNode::Kind_HtmlCell ||
kind==DocNode::Kind_ParamList)
{
t=6;
}
}
break;
}
case DocNode::Kind_AutoListItem:
//isFirst=TRUE;
//isLast =TRUE;
isFirst=isFirstChildNode((DocAutoListItem*)p->parent(),p);
isLast =isLastChildNode ((DocAutoListItem*)p->parent(),p);
t=1; // not used
......@@ -904,12 +955,6 @@ static int getParagraphContext(DocPara *p,bool &isFirst,bool &isLast)
if (isFirst) t=2;
if (isLast) t=4;
break;
case DocNode::Kind_HtmlCell:
isFirst=isFirstChildNode((DocHtmlCell*)p->parent(),p);
isLast =isLastChildNode ((DocHtmlCell*)p->parent(),p);
if (isFirst) t=5;
if (isLast) t=6;
break;
case DocNode::Kind_SimpleSect:
isFirst=isFirstChildNode((DocSimpleSect*)p->parent(),p);
isLast =isLastChildNode ((DocSimpleSect*)p->parent(),p);
......@@ -923,6 +968,12 @@ static int getParagraphContext(DocPara *p,bool &isFirst,bool &isLast)
isFirst=isLast=TRUE;
}
break;
case DocNode::Kind_HtmlCell:
isFirst=isFirstChildNode((DocHtmlCell*)p->parent(),p);
isLast =isLastChildNode ((DocHtmlCell*)p->parent(),p);
if (isFirst) t=5;
if (isLast) t=6;
break;
default:
break;
}
......@@ -955,6 +1006,7 @@ void HtmlDocVisitor::visitPre(DocPara *p)
case DocNode::Kind_XRefItem:
case DocNode::Kind_Copy:
case DocNode::Kind_HtmlBlockQuote:
case DocNode::Kind_ParBlock:
needsTag = TRUE;
break;
case DocNode::Kind_Root:
......@@ -1028,6 +1080,7 @@ void HtmlDocVisitor::visitPost(DocPara *p)
case DocNode::Kind_XRefItem:
case DocNode::Kind_Copy:
case DocNode::Kind_HtmlBlockQuote:
case DocNode::Kind_ParBlock:
needsTag = TRUE;
break;
case DocNode::Kind_Root:
......@@ -1811,6 +1864,18 @@ void HtmlDocVisitor::visitPost(DocVhdlFlow *vf)
}
}
void HtmlDocVisitor::visitPre(DocParBlock *)
{
if (m_hide) return;
}
void HtmlDocVisitor::visitPost(DocParBlock *)
{
if (m_hide) return;
}
void HtmlDocVisitor::filter(const char *str)
{
if (str==0) return;
......
......@@ -132,6 +132,8 @@ class HtmlDocVisitor : public DocVisitor
void visitPost(DocHtmlBlockQuote *);
void visitPre(DocVhdlFlow *);
void visitPost(DocVhdlFlow *);
void visitPre(DocParBlock *);
void visitPost(DocParBlock *);
private:
......
......@@ -1577,6 +1577,16 @@ void LatexDocVisitor::visitPost(DocVhdlFlow *)
if (m_hide) return;
}
void LatexDocVisitor::visitPre(DocParBlock *)
{
if (m_hide) return;
}
void LatexDocVisitor::visitPost(DocParBlock *)
{
if (m_hide) return;
}
void LatexDocVisitor::filter(const char *str)
{
filterLatexString(m_t,str,m_insideTabbing,m_insidePre,m_insideItem);
......
......@@ -134,6 +134,8 @@ class LatexDocVisitor : public DocVisitor
void visitPost(DocHtmlBlockQuote *);
void visitPre(DocVhdlFlow *);
void visitPost(DocVhdlFlow *);
void visitPre(DocParBlock *);
void visitPost(DocParBlock *);
private:
......
......@@ -1002,6 +1002,14 @@ void ManDocVisitor::visitPost(DocVhdlFlow *)
{
}
void ManDocVisitor::visitPre(DocParBlock *)
{
}
void ManDocVisitor::visitPost(DocParBlock *)
{
}
void ManDocVisitor::filter(const char *str)
{
......
......@@ -133,6 +133,8 @@ class ManDocVisitor : public DocVisitor
void visitPost(DocHtmlBlockQuote *);
void visitPre(DocVhdlFlow *);
void visitPost(DocVhdlFlow *);
void visitPre(DocParBlock *);
void visitPost(DocParBlock *);
private:
......
......@@ -390,6 +390,8 @@ public:
void visitPost(DocHtmlBlockQuote *);
void visitPre(DocVhdlFlow *);
void visitPost(DocVhdlFlow *);
void visitPre(DocParBlock *);
void visitPost(DocParBlock *);
private:
......@@ -1405,6 +1407,15 @@ void PerlModDocVisitor::visitPost(DocVhdlFlow *)
{
}
void PerlModDocVisitor::visitPre(DocParBlock *)
{
}
void PerlModDocVisitor::visitPost(DocParBlock *)
{
}
static void addTemplateArgumentList(ArgumentList *al,PerlModOutput &output,const char *)
{
QCString indentStr;
......
......@@ -761,6 +761,16 @@ class PrintDocVisitor : public DocVisitor
indent_post();
printf("</vhdlflow>\n");
}
void visitPre(DocParBlock *)
{
indent_pre();
printf("<parblock>\n");
}
void visitPost(DocParBlock *)
{
indent_post();
printf("</parblock>\n");
}
private:
// helper functions
......
......@@ -1686,6 +1686,16 @@ void RTFDocVisitor::visitPost(DocVhdlFlow *)
if (m_hide) return;
}
void RTFDocVisitor::visitPre(DocParBlock *)
{
if (m_hide) return;
}
void RTFDocVisitor::visitPost(DocParBlock *)
{
if (m_hide) return;
}
//static char* getMultiByte(int c)
//{
......
......@@ -131,6 +131,8 @@ class RTFDocVisitor : public DocVisitor
void visitPost(DocHtmlBlockQuote *);
void visitPre(DocVhdlFlow *);
void visitPost(DocVhdlFlow *);
void visitPre(DocParBlock *);
void visitPost(DocParBlock *);
private:
......
......@@ -130,6 +130,8 @@ class TextDocVisitor : public DocVisitor
void visitPost(DocHtmlBlockQuote *) {}
void visitPre(DocVhdlFlow *) {}
void visitPost(DocVhdlFlow *) {}
void visitPre(DocParBlock *) {}
void visitPost(DocParBlock *) {}
private:
......
......@@ -1068,6 +1068,19 @@ void XmlDocVisitor::visitPost(DocVhdlFlow *)
{
}
void XmlDocVisitor::visitPre(DocParBlock *)
{
if (m_hide) return;
m_t << "<parblock>";
}
void XmlDocVisitor::visitPost(DocParBlock *)
{
if (m_hide) return;
m_t << "</parblock>";
}
void XmlDocVisitor::filter(const char *str)
{
m_t << convertToXML(str);
......
......@@ -135,6 +135,8 @@ class XmlDocVisitor : public DocVisitor
void visitPost(DocHtmlBlockQuote *);
void visitPre(DocVhdlFlow *);
void visitPost(DocVhdlFlow *);
void visitPre(DocParBlock *);
void visitPost(DocParBlock *);
private:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment