Adds "smart" line flushing functions.

See in-code comments for more details
This commit is contained in:
Nokome Bentley 2015-07-13 15:40:59 +12:00
parent 0d02731679
commit f6979787d1

View file

@ -711,6 +711,42 @@ static void PCondFlushLine( TidyDocImpl* doc, uint indent )
} }
} }
/**
* Two additional "smart" flush line functions which only
* write a newline if `vertical-space no`. See issues #163 and #227.
* These need to be used in the right place. In same cases `PFlushLine`
* and `PCondFlushLine` should still be used.
*/
void TY_(PFlushLineSmart)( TidyDocImpl* doc, uint indent )
{
TidyPrintImpl* pprint = &doc->pprint;
if ( pprint->linelen > 0 )
PFlushLineImpl( doc );
Bool vertical = cfgBool( doc, TidyVertSpace );
if(vertical)
TY_(WriteChar)( '\n', doc->docOut );
pprint->indent[ 0 ].spaces = indent;
}
static void PCondFlushLineSmart( TidyDocImpl* doc, uint indent )
{
TidyPrintImpl* pprint = &doc->pprint;
if ( pprint->linelen > 0 )
{
PFlushLineImpl( doc );
Bool vertical = cfgBool( doc, TidyVertSpace );
if(vertical)
TY_(WriteChar)( '\n', doc->docOut );
pprint->indent[ 0 ].spaces = indent;
}
}
static void PPrintChar( TidyDocImpl* doc, uint c, uint mode ) static void PPrintChar( TidyDocImpl* doc, uint c, uint mode )
{ {
tmbchar entity[128]; tmbchar entity[128];
@ -1164,7 +1200,7 @@ static void PPrintAttribute( TidyDocImpl* doc, uint indent,
if ( TY_(nodeIsElement)(node) && !first ) if ( TY_(nodeIsElement)(node) && !first )
{ {
indent += xtra; indent += xtra;
PCondFlushLine( doc, indent ); PCondFlushLineSmart( doc, indent );
} }
else else
indAttrs = no; indAttrs = no;
@ -1471,7 +1507,7 @@ static void PPrintTag( TidyDocImpl* doc,
See bug #996484 */ See bug #996484 */
else if ( mode & NOWRAP || else if ( mode & NOWRAP ||
nodeIsBR(node) || AfterSpace(doc->lexer, node)) nodeIsBR(node) || AfterSpace(doc->lexer, node))
PCondFlushLine( doc, indent ); PCondFlushLineSmart( doc, indent );
} }
} }
@ -1536,7 +1572,7 @@ static void PPrintComment( TidyDocImpl* doc, uint indent, Node* node )
AddString(pprint, "--"); AddString(pprint, "--");
AddChar( pprint, '>' ); AddChar( pprint, '>' );
if ( node->linebreak && node->next ) if ( node->linebreak && node->next )
TY_(PFlushLine)( doc, indent ); TY_(PFlushLineSmart)( doc, indent );
} }
static void PPrintDocType( TidyDocImpl* doc, uint indent, Node *node ) static void PPrintDocType( TidyDocImpl* doc, uint indent, Node *node )
@ -1550,7 +1586,7 @@ static void PPrintDocType( TidyDocImpl* doc, uint indent, Node *node )
/* todo: handle non-ASCII characters in FPI / SI / node->element */ /* todo: handle non-ASCII characters in FPI / SI / node->element */
SetWrap( doc, indent ); SetWrap( doc, indent );
PCondFlushLine( doc, indent ); PCondFlushLineSmart( doc, indent );
AddString( pprint, "<!DOCTYPE " ); AddString( pprint, "<!DOCTYPE " );
SetWrap( doc, indent ); SetWrap( doc, indent );
@ -1573,7 +1609,7 @@ static void PPrintDocType( TidyDocImpl* doc, uint indent, Node *node )
if (!(i>0&&TY_(tmbstrlen)(sys->value)+2+i<wraplen&&i<=(spaces?spaces:2)*2)) if (!(i>0&&TY_(tmbstrlen)(sys->value)+2+i<wraplen&&i<=(spaces?spaces:2)*2))
i = 0; i = 0;
PCondFlushLine(doc, i); PCondFlushLineSmart(doc, i);
if (pprint->linelen) if (pprint->linelen)
AddChar(pprint, ' '); AddChar(pprint, ' ');
} }
@ -1591,7 +1627,7 @@ static void PPrintDocType( TidyDocImpl* doc, uint indent, Node *node )
if (node->content) if (node->content)
{ {
PCondFlushLine(doc, indent); PCondFlushLineSmart(doc, indent);
AddChar(pprint, '['); AddChar(pprint, '[');
PPrintText(doc, CDATA, 0, node->content); PPrintText(doc, CDATA, 0, node->content);
AddChar(pprint, ']'); AddChar(pprint, ']');
@ -1599,7 +1635,7 @@ static void PPrintDocType( TidyDocImpl* doc, uint indent, Node *node )
SetWrap( doc, 0 ); SetWrap( doc, 0 );
AddChar( pprint, '>' ); AddChar( pprint, '>' );
PCondFlushLine( doc, indent ); PCondFlushLineSmart( doc, indent );
} }
static void PPrintPI( TidyDocImpl* doc, uint indent, Node *node ) static void PPrintPI( TidyDocImpl* doc, uint indent, Node *node )
@ -1664,7 +1700,7 @@ static void PPrintXmlDecl( TidyDocImpl* doc, uint indent, Node *node )
AddChar( pprint, '?' ); AddChar( pprint, '?' );
AddChar( pprint, '>' ); AddChar( pprint, '>' );
WrapOn( doc, saveWrap ); WrapOn( doc, saveWrap );
TY_(PFlushLine)( doc, indent ); TY_(PFlushLineSmart)( doc, indent );
} }
/* note ASP and JSTE share <% ... %> syntax */ /* note ASP and JSTE share <% ... %> syntax */
@ -1729,14 +1765,14 @@ static void PPrintCDATA( TidyDocImpl* doc, uint indent, Node *node )
if ( !indentCData ) if ( !indentCData )
indent = 0; indent = 0;
PCondFlushLine( doc, indent ); PCondFlushLineSmart( doc, indent );
saveWrap = WrapOff( doc ); /* disable wrapping */ saveWrap = WrapOff( doc ); /* disable wrapping */
AddString( pprint, "<![CDATA[" ); AddString( pprint, "<![CDATA[" );
PPrintText( doc, COMMENT, indent, node ); PPrintText( doc, COMMENT, indent, node );
AddString( pprint, "]]>" ); AddString( pprint, "]]>" );
PCondFlushLine( doc, indent ); PCondFlushLineSmart( doc, indent );
WrapOn( doc, saveWrap ); /* restore wrapping */ WrapOn( doc, saveWrap ); /* restore wrapping */
} }
@ -1889,9 +1925,9 @@ void PPrintScriptStyle( TidyDocImpl* doc, uint mode, uint indent, Node *node )
Bool xhtmlOut = cfgBool( doc, TidyXhtmlOut ); Bool xhtmlOut = cfgBool( doc, TidyXhtmlOut );
if ( InsideHead(doc, node) ) if ( InsideHead(doc, node) )
TY_(PFlushLine)( doc, indent ); TY_(PFlushLineSmart)( doc, indent );
PCondFlushLine( doc, indent ); /* Issue #56 - long oustanding bug - flush any existing closing tag */ PCondFlushLineSmart( doc, indent ); /* Issue #56 - long oustanding bug - flush any existing closing tag */
PPrintTag( doc, mode, indent, node ); PPrintTag( doc, mode, indent, node );
@ -1928,7 +1964,7 @@ void PPrintScriptStyle( TidyDocImpl* doc, uint mode, uint indent, Node *node )
AddString( pprint, commentStart ); AddString( pprint, commentStart );
AddString( pprint, CDATA_START ); AddString( pprint, CDATA_START );
AddString( pprint, commentEnd ); AddString( pprint, commentEnd );
PCondFlushLine( doc, indent ); PCondFlushLineSmart( doc, indent );
WrapOn( doc, saveWrap ); WrapOn( doc, saveWrap );
} }
@ -1952,7 +1988,7 @@ void PPrintScriptStyle( TidyDocImpl* doc, uint mode, uint indent, Node *node )
if ( contentIndent < 0 ) if ( contentIndent < 0 )
{ {
PCondFlushLine( doc, indent ); PCondFlushLineSmart( doc, indent );
contentIndent = 0; contentIndent = 0;
} }
@ -1967,7 +2003,7 @@ void PPrintScriptStyle( TidyDocImpl* doc, uint mode, uint indent, Node *node )
AddString( pprint, commentEnd ); AddString( pprint, commentEnd );
WrapOn( doc, saveWrap ); WrapOn( doc, saveWrap );
PCondFlushLine( doc, indent ); PCondFlushLineSmart( doc, indent );
} }
} }
@ -1979,7 +2015,7 @@ void PPrintScriptStyle( TidyDocImpl* doc, uint mode, uint indent, Node *node )
if ( cfgAutoBool(doc, TidyIndentContent) == TidyNoState if ( cfgAutoBool(doc, TidyIndentContent) == TidyNoState
&& node->next != NULL && && node->next != NULL &&
!( TY_(nodeHasCM)(node, CM_INLINE) || TY_(nodeIsText)(node) ) ) !( TY_(nodeHasCM)(node, CM_INLINE) || TY_(nodeIsText)(node) ) )
TY_(PFlushLine)( doc, indent ); TY_(PFlushLineSmart)( doc, indent );
} }
@ -2112,12 +2148,12 @@ void TY_(PPrintTree)( TidyDocImpl* doc, uint mode, uint indent, Node *node )
or remove the CM_INLINE from the tag or remove the CM_INLINE from the tag
*/ */
if ( ! TY_(nodeHasCM)(node, CM_INLINE) ) if ( ! TY_(nodeHasCM)(node, CM_INLINE) )
PCondFlushLine( doc, indent ); PCondFlushLineSmart( doc, indent );
if ( nodeIsBR(node) && node->prev && if ( nodeIsBR(node) && node->prev &&
!(nodeIsBR(node->prev) || (mode & PREFORMATTED)) && !(nodeIsBR(node->prev) || (mode & PREFORMATTED)) &&
cfgBool(doc, TidyBreakBeforeBR) ) cfgBool(doc, TidyBreakBeforeBR) )
TY_(PFlushLine)( doc, indent ); TY_(PFlushLineSmart)( doc, indent );
if ( nodeIsHR(node) ) if ( nodeIsHR(node) )
{ {
@ -2125,7 +2161,7 @@ void TY_(PPrintTree)( TidyDocImpl* doc, uint mode, uint indent, Node *node )
Bool classic = cfgBool( doc, TidyVertSpace ); Bool classic = cfgBool( doc, TidyVertSpace );
if (classic && node->parent && node->parent->content != node) if (classic && node->parent && node->parent->content != node)
{ {
TY_(PFlushLine)( doc, indent ); TY_(PFlushLineSmart)( doc, indent );
} }
} }
@ -2134,10 +2170,10 @@ void TY_(PPrintTree)( TidyDocImpl* doc, uint mode, uint indent, Node *node )
if (node->next) if (node->next)
{ {
if (nodeIsPARAM(node) || nodeIsAREA(node)) if (nodeIsPARAM(node) || nodeIsAREA(node))
PCondFlushLine(doc, indent); PCondFlushLineSmart(doc, indent);
else if ((nodeIsBR(node) && !(mode & PREFORMATTED)) else if ((nodeIsBR(node) && !(mode & PREFORMATTED))
|| nodeIsHR(node)) || nodeIsHR(node))
TY_(PFlushLine)(doc, indent); TY_(PFlushLineSmart)(doc, indent);
} }
} }
else /* some kind of container element */ else /* some kind of container element */
@ -2150,32 +2186,32 @@ void TY_(PPrintTree)( TidyDocImpl* doc, uint mode, uint indent, Node *node )
{ {
Bool classic = cfgBool( doc, TidyVertSpace ); Bool classic = cfgBool( doc, TidyVertSpace );
uint indprev = indent; uint indprev = indent;
PCondFlushLine( doc, indent ); PCondFlushLineSmart( doc, indent );
PCondFlushLine( doc, indent ); PCondFlushLineSmart( doc, indent );
/* insert extra newline for classic formatting */ /* insert extra newline for classic formatting */
if (classic && node->parent && node->parent->content != node) if (classic && node->parent && node->parent->content != node)
{ {
TY_(PFlushLine)( doc, indent ); TY_(PFlushLineSmart)( doc, indent );
} }
PPrintTag( doc, mode, indent, node ); PPrintTag( doc, mode, indent, node );
indent = 0; indent = 0;
TY_(PFlushLine)( doc, indent ); TY_(PFlushLineSmart)( doc, indent );
for ( content = node->content; content; content = content->next ) for ( content = node->content; content; content = content->next )
{ {
TY_(PPrintTree)( doc, (mode | PREFORMATTED | NOWRAP), TY_(PPrintTree)( doc, (mode | PREFORMATTED | NOWRAP),
indent, content ); indent, content );
} }
PCondFlushLine( doc, indent ); PCondFlushLineSmart( doc, indent );
indent = indprev; indent = indprev;
PPrintEndTag( doc, mode, indent, node ); PPrintEndTag( doc, mode, indent, node );
if ( cfgAutoBool(doc, TidyIndentContent) == TidyNoState if ( cfgAutoBool(doc, TidyIndentContent) == TidyNoState
&& node->next != NULL ) && node->next != NULL )
TY_(PFlushLine)( doc, indent ); TY_(PFlushLineSmart)( doc, indent );
} }
else if ( nodeIsSTYLE(node) || nodeIsSCRIPT(node) ) else if ( nodeIsSTYLE(node) || nodeIsSCRIPT(node) )
{ {
@ -2204,7 +2240,7 @@ void TY_(PPrintTree)( TidyDocImpl* doc, uint mode, uint indent, Node *node )
if ( ShouldIndent(doc, node) ) if ( ShouldIndent(doc, node) )
{ {
indent += spaces; indent += spaces;
PCondFlushLine( doc, indent ); PCondFlushLineSmart( doc, indent );
for ( content = node->content; for ( content = node->content;
content != NULL; content != NULL;
@ -2212,7 +2248,7 @@ void TY_(PPrintTree)( TidyDocImpl* doc, uint mode, uint indent, Node *node )
TY_(PPrintTree)( doc, mode, indent, content ); TY_(PPrintTree)( doc, mode, indent, content );
indent -= spaces; indent -= spaces;
PCondFlushLine( doc, indent ); PCondFlushLineSmart( doc, indent );
/* PCondFlushLine( doc, indent ); */ /* PCondFlushLine( doc, indent ); */
} }
else else
@ -2236,13 +2272,13 @@ void TY_(PPrintTree)( TidyDocImpl* doc, uint mode, uint indent, Node *node )
/* insert extra newline for classic formatting */ /* insert extra newline for classic formatting */
if (classic && node->parent && node->parent->content != node && !nodeIsHTML(node)) if (classic && node->parent && node->parent->content != node && !nodeIsHTML(node))
{ {
TY_(PFlushLine)( doc, indent ); TY_(PFlushLineSmart)( doc, indent );
} }
if ( ShouldIndent(doc, node) ) if ( ShouldIndent(doc, node) )
contentIndent += spaces; contentIndent += spaces;
PCondFlushLine( doc, indent ); PCondFlushLineSmart( doc, indent );
/*\ /*\
* Issue #180 - with the above PCondFlushLine, * Issue #180 - with the above PCondFlushLine,
@ -2250,7 +2286,7 @@ void TY_(PPrintTree)( TidyDocImpl* doc, uint mode, uint indent, Node *node )
* Maybe only if 'classic' ie --vertical-space yes * Maybe only if 'classic' ie --vertical-space yes
\*/ \*/
if ( indsmart && node->prev != NULL && classic) if ( indsmart && node->prev != NULL && classic)
TY_(PFlushLine)( doc, indent ); TY_(PFlushLineSmart)( doc, indent );
/* do not omit elements with attributes */ /* do not omit elements with attributes */
if ( !hideend || !TY_(nodeHasCM)(node, CM_OMITST) || if ( !hideend || !TY_(nodeHasCM)(node, CM_OMITST) ||
@ -2263,11 +2299,11 @@ void TY_(PPrintTree)( TidyDocImpl* doc, uint mode, uint indent, Node *node )
/* fix for bug 530791, don't wrap after */ /* fix for bug 530791, don't wrap after */
/* <li> if first child is text node */ /* <li> if first child is text node */
if (!(nodeIsLI(node) && TY_(nodeIsText)(node->content))) if (!(nodeIsLI(node) && TY_(nodeIsText)(node->content)))
PCondFlushLine( doc, contentIndent ); PCondFlushLineSmart( doc, contentIndent );
} }
else if ( TY_(nodeHasCM)(node, CM_HTML) || nodeIsNOFRAMES(node) || else if ( TY_(nodeHasCM)(node, CM_HTML) || nodeIsNOFRAMES(node) ||
(TY_(nodeHasCM)(node, CM_HEAD) && !nodeIsTITLE(node)) ) (TY_(nodeHasCM)(node, CM_HEAD) && !nodeIsTITLE(node)) )
TY_(PFlushLine)( doc, contentIndent ); TY_(PFlushLineSmart)( doc, contentIndent );
} }
last = NULL; last = NULL;
@ -2278,7 +2314,7 @@ void TY_(PPrintTree)( TidyDocImpl* doc, uint mode, uint indent, Node *node )
content->tag && !TY_(nodeHasCM)(content, CM_INLINE) ) content->tag && !TY_(nodeHasCM)(content, CM_INLINE) )
{ {
/* TY_(PFlushLine)(fout, indent); */ /* TY_(PFlushLine)(fout, indent); */
TY_(PFlushLine)( doc, contentIndent ); TY_(PFlushLineSmart)( doc, contentIndent );
} }
TY_(PPrintTree)( doc, mode, contentIndent, content ); TY_(PPrintTree)( doc, mode, contentIndent, content );
@ -2295,7 +2331,7 @@ void TY_(PPrintTree)( TidyDocImpl* doc, uint mode, uint indent, Node *node )
) )
) )
{ {
PCondFlushLine( doc, indent ); PCondFlushLineSmart( doc, indent );
if ( !hideend || !TY_(nodeHasCM)(node, CM_OPT) ) if ( !hideend || !TY_(nodeHasCM)(node, CM_OPT) )
{ {
PPrintEndTag( doc, mode, indent, node ); PPrintEndTag( doc, mode, indent, node );
@ -2308,15 +2344,15 @@ void TY_(PPrintTree)( TidyDocImpl* doc, uint mode, uint indent, Node *node )
{ {
/* newline before endtag for classic formatting */ /* newline before endtag for classic formatting */
if ( classic && !HasMixedContent(node) ) if ( classic && !HasMixedContent(node) )
TY_(PFlushLine)( doc, indent ); TY_(PFlushLineSmart)( doc, indent );
PPrintEndTag( doc, mode, indent, node ); PPrintEndTag( doc, mode, indent, node );
} }
} }
if (!indcont && !hideend && !nodeIsHTML(node) && !classic) if (!indcont && !hideend && !nodeIsHTML(node) && !classic)
TY_(PFlushLine)( doc, indent ); TY_(PFlushLineSmart)( doc, indent );
else if (classic && node->next != NULL && TY_(nodeHasCM)(node, CM_LIST|CM_DEFLIST|CM_TABLE|CM_BLOCK/*|CM_HEADING*/)) else if (classic && node->next != NULL && TY_(nodeHasCM)(node, CM_LIST|CM_DEFLIST|CM_TABLE|CM_BLOCK/*|CM_HEADING*/))
TY_(PFlushLine)( doc, indent ); TY_(PFlushLineSmart)( doc, indent );
} }
} }
} }
@ -2333,7 +2369,7 @@ void TY_(PPrintXMLTree)( TidyDocImpl* doc, uint mode, uint indent, Node *node )
} }
else if ( node->type == CommentTag ) else if ( node->type == CommentTag )
{ {
PCondFlushLine( doc, indent ); PCondFlushLineSmart( doc, indent );
PPrintComment( doc, indent, node); PPrintComment( doc, indent, node);
/* PCondFlushLine( doc, 0 ); */ /* PCondFlushLine( doc, 0 ); */
} }
@ -2364,7 +2400,7 @@ void TY_(PPrintXMLTree)( TidyDocImpl* doc, uint mode, uint indent, Node *node )
else if ( TY_(nodeHasCM)(node, CM_EMPTY) || else if ( TY_(nodeHasCM)(node, CM_EMPTY) ||
(node->type == StartEndTag && !xhtmlOut) ) (node->type == StartEndTag && !xhtmlOut) )
{ {
PCondFlushLine( doc, indent ); PCondFlushLineSmart( doc, indent );
PPrintTag( doc, mode, indent, node ); PPrintTag( doc, mode, indent, node );
/* TY_(PFlushLine)( doc, indent ); */ /* TY_(PFlushLine)( doc, indent ); */
} }
@ -2384,7 +2420,7 @@ void TY_(PPrintXMLTree)( TidyDocImpl* doc, uint mode, uint indent, Node *node )
} }
} }
PCondFlushLine( doc, indent ); PCondFlushLineSmart( doc, indent );
if ( TY_(XMLPreserveWhiteSpace)(doc, node) ) if ( TY_(XMLPreserveWhiteSpace)(doc, node) )
{ {
@ -2399,13 +2435,13 @@ void TY_(PPrintXMLTree)( TidyDocImpl* doc, uint mode, uint indent, Node *node )
PPrintTag( doc, mode, indent, node ); PPrintTag( doc, mode, indent, node );
if ( !mixed && node->content ) if ( !mixed && node->content )
TY_(PFlushLine)( doc, cindent ); TY_(PFlushLineSmart)( doc, cindent );
for ( content = node->content; content; content = content->next ) for ( content = node->content; content; content = content->next )
TY_(PPrintXMLTree)( doc, mode, cindent, content ); TY_(PPrintXMLTree)( doc, mode, cindent, content );
if ( !mixed && node->content ) if ( !mixed && node->content )
PCondFlushLine( doc, indent ); PCondFlushLineSmart( doc, indent );
PPrintEndTag( doc, mode, indent, node ); PPrintEndTag( doc, mode, indent, node );
/* PCondFlushLine( doc, indent ); */ /* PCondFlushLine( doc, indent ); */