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 )
{
tmbchar entity[128];
@ -1164,7 +1200,7 @@ static void PPrintAttribute( TidyDocImpl* doc, uint indent,
if ( TY_(nodeIsElement)(node) && !first )
{
indent += xtra;
PCondFlushLine( doc, indent );
PCondFlushLineSmart( doc, indent );
}
else
indAttrs = no;
@ -1471,7 +1507,7 @@ static void PPrintTag( TidyDocImpl* doc,
See bug #996484 */
else if ( mode & NOWRAP ||
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, "--");
AddChar( pprint, '>' );
if ( node->linebreak && node->next )
TY_(PFlushLine)( doc, indent );
TY_(PFlushLineSmart)( doc, indent );
}
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 */
SetWrap( doc, indent );
PCondFlushLine( doc, indent );
PCondFlushLineSmart( doc, indent );
AddString( pprint, "<!DOCTYPE " );
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))
i = 0;
PCondFlushLine(doc, i);
PCondFlushLineSmart(doc, i);
if (pprint->linelen)
AddChar(pprint, ' ');
}
@ -1591,7 +1627,7 @@ static void PPrintDocType( TidyDocImpl* doc, uint indent, Node *node )
if (node->content)
{
PCondFlushLine(doc, indent);
PCondFlushLineSmart(doc, indent);
AddChar(pprint, '[');
PPrintText(doc, CDATA, 0, node->content);
AddChar(pprint, ']');
@ -1599,7 +1635,7 @@ static void PPrintDocType( TidyDocImpl* doc, uint indent, Node *node )
SetWrap( doc, 0 );
AddChar( pprint, '>' );
PCondFlushLine( doc, indent );
PCondFlushLineSmart( doc, indent );
}
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, '>' );
WrapOn( doc, saveWrap );
TY_(PFlushLine)( doc, indent );
TY_(PFlushLineSmart)( doc, indent );
}
/* note ASP and JSTE share <% ... %> syntax */
@ -1729,14 +1765,14 @@ static void PPrintCDATA( TidyDocImpl* doc, uint indent, Node *node )
if ( !indentCData )
indent = 0;
PCondFlushLine( doc, indent );
PCondFlushLineSmart( doc, indent );
saveWrap = WrapOff( doc ); /* disable wrapping */
AddString( pprint, "<![CDATA[" );
PPrintText( doc, COMMENT, indent, node );
AddString( pprint, "]]>" );
PCondFlushLine( doc, indent );
PCondFlushLineSmart( doc, indent );
WrapOn( doc, saveWrap ); /* restore wrapping */
}
@ -1889,9 +1925,9 @@ void PPrintScriptStyle( TidyDocImpl* doc, uint mode, uint indent, Node *node )
Bool xhtmlOut = cfgBool( doc, TidyXhtmlOut );
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 );
@ -1928,7 +1964,7 @@ void PPrintScriptStyle( TidyDocImpl* doc, uint mode, uint indent, Node *node )
AddString( pprint, commentStart );
AddString( pprint, CDATA_START );
AddString( pprint, commentEnd );
PCondFlushLine( doc, indent );
PCondFlushLineSmart( doc, indent );
WrapOn( doc, saveWrap );
}
@ -1952,7 +1988,7 @@ void PPrintScriptStyle( TidyDocImpl* doc, uint mode, uint indent, Node *node )
if ( contentIndent < 0 )
{
PCondFlushLine( doc, indent );
PCondFlushLineSmart( doc, indent );
contentIndent = 0;
}
@ -1967,7 +2003,7 @@ void PPrintScriptStyle( TidyDocImpl* doc, uint mode, uint indent, Node *node )
AddString( pprint, commentEnd );
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
&& node->next != NULL &&
!( 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
*/
if ( ! TY_(nodeHasCM)(node, CM_INLINE) )
PCondFlushLine( doc, indent );
PCondFlushLineSmart( doc, indent );
if ( nodeIsBR(node) && node->prev &&
!(nodeIsBR(node->prev) || (mode & PREFORMATTED)) &&
cfgBool(doc, TidyBreakBeforeBR) )
TY_(PFlushLine)( doc, indent );
TY_(PFlushLineSmart)( doc, indent );
if ( nodeIsHR(node) )
{
@ -2125,7 +2161,7 @@ void TY_(PPrintTree)( TidyDocImpl* doc, uint mode, uint indent, Node *node )
Bool classic = cfgBool( doc, TidyVertSpace );
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 (nodeIsPARAM(node) || nodeIsAREA(node))
PCondFlushLine(doc, indent);
PCondFlushLineSmart(doc, indent);
else if ((nodeIsBR(node) && !(mode & PREFORMATTED))
|| nodeIsHR(node))
TY_(PFlushLine)(doc, indent);
TY_(PFlushLineSmart)(doc, indent);
}
}
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 );
uint indprev = indent;
PCondFlushLine( doc, indent );
PCondFlushLineSmart( doc, indent );
PCondFlushLine( doc, indent );
PCondFlushLineSmart( doc, indent );
/* insert extra newline for classic formatting */
if (classic && node->parent && node->parent->content != node)
{
TY_(PFlushLine)( doc, indent );
TY_(PFlushLineSmart)( doc, indent );
}
PPrintTag( doc, mode, indent, node );
indent = 0;
TY_(PFlushLine)( doc, indent );
TY_(PFlushLineSmart)( doc, indent );
for ( content = node->content; content; content = content->next )
{
TY_(PPrintTree)( doc, (mode | PREFORMATTED | NOWRAP),
indent, content );
}
PCondFlushLine( doc, indent );
PCondFlushLineSmart( doc, indent );
indent = indprev;
PPrintEndTag( doc, mode, indent, node );
if ( cfgAutoBool(doc, TidyIndentContent) == TidyNoState
&& node->next != NULL )
TY_(PFlushLine)( doc, indent );
TY_(PFlushLineSmart)( doc, indent );
}
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) )
{
indent += spaces;
PCondFlushLine( doc, indent );
PCondFlushLineSmart( doc, indent );
for ( content = node->content;
content != NULL;
@ -2212,7 +2248,7 @@ void TY_(PPrintTree)( TidyDocImpl* doc, uint mode, uint indent, Node *node )
TY_(PPrintTree)( doc, mode, indent, content );
indent -= spaces;
PCondFlushLine( doc, indent );
PCondFlushLineSmart( doc, indent );
/* PCondFlushLine( doc, indent ); */
}
else
@ -2236,13 +2272,13 @@ void TY_(PPrintTree)( TidyDocImpl* doc, uint mode, uint indent, Node *node )
/* insert extra newline for classic formatting */
if (classic && node->parent && node->parent->content != node && !nodeIsHTML(node))
{
TY_(PFlushLine)( doc, indent );
TY_(PFlushLineSmart)( doc, indent );
}
if ( ShouldIndent(doc, node) )
contentIndent += spaces;
PCondFlushLine( doc, indent );
PCondFlushLineSmart( doc, indent );
/*\
* 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
\*/
if ( indsmart && node->prev != NULL && classic)
TY_(PFlushLine)( doc, indent );
TY_(PFlushLineSmart)( doc, indent );
/* do not omit elements with attributes */
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 */
/* <li> if first child is text node */
if (!(nodeIsLI(node) && TY_(nodeIsText)(node->content)))
PCondFlushLine( doc, contentIndent );
PCondFlushLineSmart( doc, contentIndent );
}
else if ( TY_(nodeHasCM)(node, CM_HTML) || nodeIsNOFRAMES(node) ||
(TY_(nodeHasCM)(node, CM_HEAD) && !nodeIsTITLE(node)) )
TY_(PFlushLine)( doc, contentIndent );
TY_(PFlushLineSmart)( doc, contentIndent );
}
last = NULL;
@ -2278,7 +2314,7 @@ void TY_(PPrintTree)( TidyDocImpl* doc, uint mode, uint indent, Node *node )
content->tag && !TY_(nodeHasCM)(content, CM_INLINE) )
{
/* TY_(PFlushLine)(fout, indent); */
TY_(PFlushLine)( doc, contentIndent );
TY_(PFlushLineSmart)( doc, contentIndent );
}
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) )
{
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 */
if ( classic && !HasMixedContent(node) )
TY_(PFlushLine)( doc, indent );
TY_(PFlushLineSmart)( doc, indent );
PPrintEndTag( doc, mode, indent, node );
}
}
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*/))
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 )
{
PCondFlushLine( doc, indent );
PCondFlushLineSmart( doc, indent );
PPrintComment( doc, indent, node);
/* 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) ||
(node->type == StartEndTag && !xhtmlOut) )
{
PCondFlushLine( doc, indent );
PCondFlushLineSmart( doc, indent );
PPrintTag( doc, mode, indent, node );
/* 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) )
{
@ -2399,13 +2435,13 @@ void TY_(PPrintXMLTree)( TidyDocImpl* doc, uint mode, uint indent, Node *node )
PPrintTag( doc, mode, indent, node );
if ( !mixed && node->content )
TY_(PFlushLine)( doc, cindent );
TY_(PFlushLineSmart)( doc, cindent );
for ( content = node->content; content; content = content->next )
TY_(PPrintXMLTree)( doc, mode, cindent, content );
if ( !mixed && node->content )
PCondFlushLine( doc, indent );
PCondFlushLineSmart( doc, indent );
PPrintEndTag( doc, mode, indent, node );
/* PCondFlushLine( doc, indent ); */