Skip to content

Commit 300f73d

Browse files
committed
issue #10970 Improvement of end of paragraph detection
1 parent 1f20830 commit 300f73d

File tree

2 files changed

+91
-25
lines changed

2 files changed

+91
-25
lines changed

src/commentscan.l

Lines changed: 76 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,15 @@ enum GuardType
437437
* statics
438438
*/
439439

440+
struct HtmlContextInfo
441+
{
442+
HtmlContextInfo(const QCString &tn,OutputContext ctx) : tagName(tn), context(ctx) {}
443+
QCString tagName;
444+
OutputContext context;
445+
};
446+
447+
using HtmlContextStack = std::vector<HtmlContextInfo>;
448+
440449
struct commentscanYY_state
441450
{
442451
OutlineParserInterface *langParser = nullptr; // the language parser that is calling us
@@ -465,6 +474,7 @@ struct commentscanYY_state
465474
Entry *current = nullptr; // working entry
466475

467476
bool needNewEntry = FALSE;
477+
HtmlContextStack htmlContextStack;
468478

469479
QCString sectionLabel;
470480
QCString sectionTitle;
@@ -489,7 +499,7 @@ struct commentscanYY_state
489499

490500
QCString guardExpr;
491501
int roundCount = 0;
492-
std::vector<int> HTMLDetailsSummary;
502+
std::vector<int> htmlDetailsStack;
493503

494504
bool insideParBlock = FALSE;
495505
bool inInternalDocs = FALSE;
@@ -554,28 +564,29 @@ static inline const char *getLexerFILE() {return __FILE__;}
554564
/* start command character */
555565
CMD ("\\"|"@")
556566
XREFCMD {CMD}("bug"|"deprecated"|"test"|"todo"|"xrefitem")
557-
PRE [pP][rR][eE]
558-
TABLE [tT][aA][bB][lL][eE]
567+
PRE ("pre"|"PRE")
568+
TABLE ("table"|"TABLE")
559569
P [pP]
560-
UL [uU][lL]
561-
OL [oO][lL]
562-
DL [dD][lL]
563-
IMG [iI][mM][gG]
564-
HR [hH][rR]
565-
PARA [pP][aA][rR][aA]
566-
CODE [cC][oO][dD][eE]
570+
UL ("ul"|"UL")
571+
OL ("ol"|"OL")
572+
DL ("dl"|"DL")
573+
IMG ("img"|"IMG")
574+
HR ("hr"|"HR")
575+
PARA ("para"|"PARA")
576+
CODE ("code"|"CODE")
567577
ENDCODE "/"{CODE}
568-
CAPTION [cC][aA][pP][tT][iI][oO][nN]
569-
CENTER [cC][eE][nN][tT][eE][rR]
570-
DIV [dD][iI][vV]
571-
DETAILS [dD][eE][tT][aA][iI][lL][sS]
572-
DETAILEDHTML {CENTER}|{DIV}|{PRE}|{UL}|{TABLE}|{OL}|{DL}|{P}|[Hh][1-6]|{IMG}|{HR}|{PARA}
578+
CAPTION ("caption"|"CAPTION")
579+
CENTER ("center"|"CENTER")
580+
DIV ("div"|"DIV")
581+
DETAILS ("details"|"DETAILS")
582+
BLOCKQUOTE ("blockquote"|"BLOCKQUOTE")
583+
DETAILEDHTML {CENTER}|{DIV}|{PRE}|{UL}|{TABLE}|{OL}|{DL}|{P}|[Hh][1-6]|{IMG}|{HR}|{PARA}|{BLOCKQUOTE}
573584
DETAILEDHTMLOPT {CODE}
574585
DETAILEDHTMLOPTEND {ENDCODE}
575-
SUMMARY [sS][uU][mM][mM][aA][rR][yY]
576-
REMARKS [rR][eE][mM][aA][rR][kK][sS]
586+
SUMMARY ("summary"|"SUMMARY")
587+
REMARKS ("remarks"|"REMARKS")
577588
AHTML [aA]{BN}*
578-
ANCHTML ([iI][dD]|[nN][aA][mM][eE])"="("\""{LABELID}"\""|"'"{LABELID}"'"|{LABELID})
589+
ANCHTML ("idname"|"IDNAME")"="("\""{LABELID}"\""|"'"{LABELID}"'"|{LABELID})
579590
BN [ \t\n\r]
580591
BL [ \t\r]*"\n"
581592
B [ \t]
@@ -715,10 +726,35 @@ STopt [^\n@\\]*
715726
addOutput(yyscanner,yytext);
716727
}
717728
<Comment>"<"{DETAILEDHTML}{ATTR}">" { // HTML command that ends a brief description
718-
setOutput(yyscanner,OutputDoc);
729+
QCString htmlOpenTag(yytext);
730+
int spacePos = htmlOpenTag.find(' '); // check for optional attributes
731+
if (spacePos==-1) spacePos=yyleng-1;
732+
QCString htmlTagName = htmlOpenTag.mid(1,spacePos-1);
733+
//printf("found open tag '%s'\n",qPrint(htmlTagName));
734+
yyextra->htmlContextStack.emplace_back(htmlTagName,yyextra->inContext);
735+
if (yyextra->inContext==OutputBrief)
736+
{
737+
setOutput(yyscanner,OutputDoc);
738+
}
719739
// continue with the same input
720740
REJECT;
721741
}
742+
<Comment>"</"{DETAILEDHTML}">" { // HTML command that ends a brief description
743+
QCString htmlCloseTag(yytext);
744+
QCString htmlTagName = htmlCloseTag.mid(2,htmlCloseTag.length()-3);
745+
//printf("found close tag '%s'\n",qPrint(htmlTagName));
746+
if (!yyextra->htmlContextStack.empty() &&
747+
yyextra->htmlContextStack.back().tagName==htmlTagName)
748+
{
749+
if (yyextra->inContext==OutputXRef && yyextra->htmlContextStack.back().context!=OutputXRef)
750+
{
751+
//printf("switching back to OutputDoc\n");
752+
setOutput(yyscanner,OutputDoc);
753+
}
754+
yyextra->htmlContextStack.pop_back();
755+
}
756+
REJECT;
757+
}
722758
<Comment>"<"{DETAILEDHTMLOPT}">" { // HTML <code> command that ends a brief description
723759
// without attributes
724760
if (yyextra->current->lang==SrcLangExt::CSharp)
@@ -756,14 +792,28 @@ STopt [^\n@\\]*
756792
REJECT;
757793
}
758794
<Comment>"<"{DETAILS}{ATTR}">" { // start of a HTML style details description
759-
yyextra->HTMLDetailsSummary.push_back(0);
760-
setOutput(yyscanner,OutputDoc);
795+
yyextra->htmlDetailsStack.push_back(0);
796+
yyextra->htmlContextStack.emplace_back("details",yyextra->inContext);
797+
if (yyextra->inContext==OutputBrief)
798+
{
799+
setOutput(yyscanner,OutputDoc);
800+
}
761801
addOutput(yyscanner,yytext);
762802
}
763803
<Comment>"</"{DETAILS}">" { // end of a HTML style details description
764-
if (!yyextra->HTMLDetailsSummary.empty())
804+
if (!yyextra->htmlDetailsStack.empty())
805+
{
806+
yyextra->htmlDetailsStack.pop_back();
807+
}
808+
if (!yyextra->htmlContextStack.empty() &&
809+
yyextra->htmlContextStack.back().tagName=="details")
765810
{
766-
yyextra->HTMLDetailsSummary.pop_back();
811+
if (yyextra->inContext==OutputXRef && yyextra->htmlContextStack.back().context!=OutputXRef)
812+
{
813+
//printf("switching back to OutputDoc\n");
814+
setOutput(yyscanner,OutputDoc);
815+
}
816+
yyextra->htmlContextStack.pop_back();
767817
}
768818
addOutput(yyscanner,yytext);
769819
}
@@ -827,7 +877,7 @@ STopt [^\n@\\]*
827877
yyextra->htmlAnchorStr += yytext;
828878
}
829879
<Comment>"<"{SUMMARY}">" { // start of a .NET XML style brief description
830-
if (yyextra->HTMLDetailsSummary.empty())
880+
if (yyextra->htmlDetailsStack.empty())
831881
{
832882
setOutput(yyscanner,OutputBrief);
833883
}
@@ -841,7 +891,7 @@ STopt [^\n@\\]*
841891
addOutput(yyscanner,yytext);
842892
}
843893
<Comment>"</"{SUMMARY}">" { // start of a .NET XML style detailed description
844-
if (!yyextra->HTMLDetailsSummary.empty())
894+
if (!yyextra->htmlDetailsStack.empty())
845895
{
846896
addOutput(yyscanner,yytext);
847897
}
@@ -4646,6 +4696,7 @@ bool CommentScanner::parseCommentBlock(/* in */ OutlineParserInterface *pars
46464696
yyextra->sectionLevel = 0;
46474697
yyextra->spaceBeforeCmd.clear();
46484698
yyextra->spaceBeforeIf.clear();
4699+
yyextra->htmlContextStack.clear();
46494700

46504701
DebugLex debugLex(Debug::Lex_commentscan, __FILE__, !fileName.isEmpty() ? qPrint(fileName): nullptr);
46514702
if (!yyextra->current->inbodyDocs.isEmpty() && isInbody) // separate in body fragments

src/docnode.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1324,6 +1324,11 @@ void DocHtmlSummary::parse()
13241324
}
13251325
}
13261326
parser()->tokenizer.setStatePara();
1327+
if (tok==0)
1328+
{
1329+
warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"Unexpected end of comment while inside"
1330+
" <summary> tag");
1331+
}
13271332
}
13281333

13291334
//---------------------------------------------------------------------------
@@ -1347,6 +1352,11 @@ int DocHtmlDetails::parse()
13471352
while (retval==TK_NEWPARA);
13481353
if (par) par->markLast();
13491354

1355+
if (retval==0)
1356+
{
1357+
warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"unexpected end of comment while inside <details> block");
1358+
}
1359+
13501360
if (!summary())
13511361
{
13521362
HtmlAttribList summaryAttribs;
@@ -2611,6 +2621,11 @@ int DocHtmlBlockQuote::parse()
26112621
while (retval==TK_NEWPARA);
26122622
if (par) par->markLast();
26132623

2624+
if (retval==0)
2625+
{
2626+
warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"unexpected end of comment while inside <blockquote> block");
2627+
}
2628+
26142629
AUTO_TRACE_EXIT("retval={}",DocTokenizer::retvalToString(retval));
26152630
return (retval==RetVal_EndBlockQuote) ? RetVal_OK : retval;
26162631
}

0 commit comments

Comments
 (0)