@@ -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+
440449struct 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 */
555565CMD (" \\ " |" @" )
556566XREFCMD {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 " )
559569P [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 " )
567577ENDCODE "/"{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}
573584DETAILEDHTMLOPT {CODE}
574585DETAILEDHTMLOPTEND {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 " )
577588AHTML [aA]{BN}*
578- ANCHTML ([iI][dD]|[nN][aA][ mM ][eE] )"="(" \" " {LABELID}" \" " |" '" {LABELID}" '" |{LABELID})
589+ ANCHTML (" idname " | " IDNAME " )"="(" \" " {LABELID}" \" " |" '" {LABELID}" '" |{LABELID})
579590BN [ \t\n\r]
580591BL [ \t\r]*"\n"
581592B [ \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
0 commit comments