Skip to content

Commit 7a10ea4

Browse files
committed
issue #11579 HTML-tables in markdown files with empty lines between the tags not properly rendered
1 parent 18b0d05 commit 7a10ea4

File tree

4 files changed

+91
-14
lines changed

4 files changed

+91
-14
lines changed

doc/htmlcmds.dox

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ of a HTML tag are passed on to the HTML output only
3939
<tr><td valign="top">\startendhtmltag{CENTER}</td><td valign="top">Starts and ends a section of centered text.</td></tr>
4040
<tr><td valign="top">\startendhtmltag{CAPTION}</td><td valign="top">Starts and ends a caption. Use within a table only.</td></tr>
4141
<tr><td valign="top">\startendhtmltag{CITE}</td><td valign="top">Starts and ends a section of text displayed in a font specific for citations.</td></tr>
42-
<tr><td valign="top">\startendhtmltag{CODE}</td><td valign="top">Starts and ends a piece of text displayed in a typewriter font.</td></tr>
42+
<tr><td valign="top">\startendhtmltag{CODE}</td><td valign="top">Starts and ends a piece of text displayed in a typewriter font.
4343
Note that only for C# code, this command is equivalent to
4444
\ref cmdcode "\\code" (see \ref xmltag_code "\<code\>").</td></tr>
4545
<tr><td valign="top">\startendhtmltag{DD}</td><td valign="top">Starts and ends an item description.</td></tr>
@@ -53,7 +53,7 @@ of a HTML tag are passed on to the HTML output only
5353
<tr><td valign="top">\startalign\anchor htmltag_HR \addindex "\<HR\>"\endalign<tt>\<HR\></tt></td><td valign="top">Writes a horizontal ruler.</td></tr>
5454
<tr><td valign="top">\startendhtmltag{H1}</td><td valign="top">Starts and ends an unnumbered section.</td></tr>
5555
<tr><td valign="top">\startendhtmltag{H2}</td><td valign="top">Starts and ends an unnumbered subsection.</td></tr>
56-
<tr><td valign="top">\startendhtmltag{H3}</td><td valign="top">Starts and ends an unnumbered subsubsection.</td></tr></td></tr>
56+
<tr><td valign="top">\startendhtmltag{H3}</td><td valign="top">Starts and ends an unnumbered subsubsection.</td></tr>
5757
<tr><td valign="top">\startendhtmltag{H4}</td><td valign="top">Starts and ends an unnumbered subsubsection.</td></tr>
5858
<tr><td valign="top">\startendhtmltag{H5}</td><td valign="top">Starts and ends an unnumbered subsubsection.</td></tr>
5959
<tr><td valign="top">\startendhtmltag{H6}</td><td valign="top">Starts and ends an unnumbered subsubsection.</td></tr>

src/docnode.cpp

Lines changed: 75 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1991,6 +1991,53 @@ Token DocHtmlRow::parse()
19911991
isFirst=FALSE;
19921992
retval=cell->parse();
19931993
isHeading = retval.is(TokenRetval::RetVal_TableHCell);
1994+
//printf("DocHtmlRow:retval=%s\n",retval.to_string());
1995+
if (retval.is(TokenRetval::RetVal_EndTableCell))
1996+
{
1997+
// get next token
1998+
retval=parser()->tokenizer.lex();
1999+
// skip whitespace after </td> or </th>
2000+
while (retval.is_any_of(TokenRetval::TK_WHITESPACE,TokenRetval::TK_NEWPARA)) retval=parser()->tokenizer.lex();
2001+
//printf("DocHtmlRow:retval= next=%s name=%s endTag=%d\n",retval.to_string(),qPrint(parser()->context.token->name),parser()->context.token->endTag);
2002+
HtmlTagType tagId=Mappers::htmlTagMapper->map(parser()->context.token->name);
2003+
if (tok.is(TokenRetval::TK_HTMLTAG))
2004+
{
2005+
if ((tagId==HtmlTagType::HTML_TD || tagId==HtmlTagType::HTML_TH) &&
2006+
!parser()->context.token->endTag) // found new <td> or <td> tag
2007+
{
2008+
retval = Token::make_RetVal_TableCell();
2009+
isHeading = tagId==HtmlTagType::HTML_TH;
2010+
}
2011+
else if (tagId==HtmlTagType::HTML_TR)
2012+
{
2013+
if (parser()->context.token->endTag) // found </tr> tag
2014+
{
2015+
retval = Token::make_RetVal_EndTableRow();
2016+
}
2017+
else // found <tr> tag
2018+
{
2019+
retval = Token::make_RetVal_TableRow();
2020+
}
2021+
}
2022+
else if (tagId==HtmlTagType::HTML_TABLE && parser()->context.token->endTag) // found </table>
2023+
{
2024+
retval = Token::make_RetVal_EndTable();
2025+
}
2026+
else // found some other tag
2027+
{
2028+
warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"expected <td>, <th> or <tr> tag but "
2029+
"found <{}> instead!",parser()->context.token->name);
2030+
parser()->tokenizer.pushBackHtmlTag(parser()->context.token->name);
2031+
goto endrow;
2032+
}
2033+
}
2034+
else // token other than html token
2035+
{
2036+
warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"expected <td>, <th> or <tr> tag but found {} token instead!",
2037+
tok.to_string());
2038+
goto endrow;
2039+
}
2040+
}
19942041
}
19952042
while (retval.is_any_of(TokenRetval::RetVal_TableCell,TokenRetval::RetVal_TableHCell));
19962043
cell->markLast(TRUE);
@@ -2150,6 +2197,31 @@ Token DocHtmlTable::parse()
21502197
{
21512198
children().append<DocHtmlRow>(parser(),thisVariant(),parser()->context.token->attribs);
21522199
retval = children().get_last<DocHtmlRow>()->parse();
2200+
//printf("DocHtmlTable::retval=%s\n",retval.to_string());
2201+
if (retval.is(TokenRetval::RetVal_EndTableRow))
2202+
{
2203+
// get next token
2204+
retval=parser()->tokenizer.lex();
2205+
// skip whitespace after </td> or </th>
2206+
while (retval.is_any_of(TokenRetval::TK_WHITESPACE,TokenRetval::TK_NEWPARA)) retval=parser()->tokenizer.lex();
2207+
//printf("DocHtmlTable::retval= next=%s name=%s endTag=%d\n",retval.to_string(),qPrint(parser()->context.token->name),parser()->context.token->endTag);
2208+
HtmlTagType tagId=Mappers::htmlTagMapper->map(parser()->context.token->name);
2209+
if (tagId==HtmlTagType::HTML_TR && !parser()->context.token->endTag)
2210+
{
2211+
retval = Token::make_RetVal_TableRow();
2212+
}
2213+
else if (tagId==HtmlTagType::HTML_TABLE && parser()->context.token->endTag)
2214+
{
2215+
retval = Token::make_RetVal_EndTable();
2216+
}
2217+
else // found some other tag
2218+
{
2219+
warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"expected <tr> or </table> tag but "
2220+
"found token {} instead!",retval.to_string());
2221+
retval=Token::make_RetVal_OK();
2222+
break;
2223+
}
2224+
}
21532225
}
21542226

21552227
computeTableGrid();
@@ -5431,13 +5503,13 @@ Token DocPara::handleHtmlEndTag(const QCString &tagName)
54315503
retval = Token::make_RetVal_EndTable();
54325504
break;
54335505
case HtmlTagType::HTML_TR:
5434-
// ignore </tr> tag
5506+
retval = Token::make_RetVal_EndTableRow();
54355507
break;
54365508
case HtmlTagType::HTML_TD:
5437-
// ignore </td> tag
5509+
retval = Token::make_RetVal_EndTableCell();
54385510
break;
54395511
case HtmlTagType::HTML_TH:
5440-
// ignore </th> tag
5512+
retval = Token::make_RetVal_EndTableCell();
54415513
break;
54425514
case HtmlTagType::HTML_THEAD:
54435515
case HtmlTagType::HTML_TBODY:

src/doctokenizer.h

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -60,15 +60,17 @@
6060
TKSPEC(RetVal_TableCell, 0x1000E) \
6161
TKSPEC(RetVal_TableHCell, 0x1000F) \
6262
TKSPEC(RetVal_EndTable, 0x10010) \
63-
TKSPEC(RetVal_Internal, 0x10011) \
64-
TKSPEC(RetVal_SwitchLang, 0x10012) \
65-
TKSPEC(RetVal_CloseXml, 0x10013) \
66-
TKSPEC(RetVal_EndBlockQuote, 0x10014) \
67-
TKSPEC(RetVal_CopyDoc, 0x10015) \
68-
TKSPEC(RetVal_EndInternal, 0x10016) \
69-
TKSPEC(RetVal_EndParBlock, 0x10017) \
70-
TKSPEC(RetVal_EndHtmlDetails, 0x10018) \
71-
TKSPEC(RetVal_SubSubParagraph, 0x10019)
63+
TKSPEC(RetVal_EndTableCell, 0x10011) \
64+
TKSPEC(RetVal_EndTableRow, 0x10012) \
65+
TKSPEC(RetVal_Internal, 0x10013) \
66+
TKSPEC(RetVal_SwitchLang, 0x10014) \
67+
TKSPEC(RetVal_CloseXml, 0x10015) \
68+
TKSPEC(RetVal_EndBlockQuote, 0x10016) \
69+
TKSPEC(RetVal_CopyDoc, 0x10017) \
70+
TKSPEC(RetVal_EndInternal, 0x10018) \
71+
TKSPEC(RetVal_EndParBlock, 0x10019) \
72+
TKSPEC(RetVal_EndHtmlDetails, 0x1001A) \
73+
TKSPEC(RetVal_SubSubParagraph, 0x1001B)
7274

7375
enum class TokenRetval
7476
{

src/section.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ class SectionManager : public LinkedMap<SectionInfo>
137137
//! Returns a non-owning pointer to the newly added section.
138138
SectionInfo *add(const SectionInfo &si)
139139
{
140+
//printf("SectionManager::add(%s,%s,%d,%s)\n",qPrint(si.label()),qPrint(si.fileName()),si.lineNr(),qPrint(si.title()));
140141
return LinkedMap<SectionInfo>::add(si.label(),si.fileName(),
141142
si.lineNr(),si.title(),si.type(),si.level(),si.ref());
142143
}
@@ -146,6 +147,7 @@ class SectionManager : public LinkedMap<SectionInfo>
146147
SectionInfo *add(const QCString &label, const QCString &fileName, int lineNr,
147148
const QCString &title, SectionType type, int level,const QCString &ref=QCString())
148149
{
150+
//printf("SectionManager::add(%s,%s,%d,%s)\n",qPrint(label),qPrint(fileName),lineNr,qPrint(title));
149151
return LinkedMap<SectionInfo>::add(label.data(),fileName,lineNr,title,type,level,ref);
150152
}
151153

@@ -154,6 +156,7 @@ class SectionManager : public LinkedMap<SectionInfo>
154156
SectionInfo *replace(const QCString &label, const QCString &fileName, int lineNr,
155157
const QCString &title, SectionType type, int level,const QCString &ref=QCString())
156158
{
159+
//printf("SectionManager::replace(%s,%s,%d,%s)\n",qPrint(label),qPrint(fileName),lineNr,qPrint(title));
157160
SectionInfo *si = LinkedMap<SectionInfo>::find(label.data());
158161
if (si)
159162
{

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy