Hi,

whitespace handling is a frequent problem in template languages. XSLT suffers 
from it just the same as Velocity; but XSLT has some directives to control some 
modes (xsl:strip-space, xsl:preserve-space, xml:space="preserve", etc. - see 
http://www.xmlplease.com/whitespace ).

We have debated this issue in previous Velocity threads and collected the 
opinions and suggestions in the Wiki:
  http://wiki.apache.org/velocity/VelocityWhitespaceGobbling

The original Velocity design was to markup any text (or byte) stream with 
directives and context references and have the renderer process these. Thus no 
whitespace handling would happen. But since structuring/indenting the markup in 
the template caused stray whitespaces in the output, some whitespace-gobbling 
has been taught to the parser. The design is not consistent: mostly whitespaces 
after a #set(..), #if(...) and #end are stripped, bot not before directives.

As you can see in the wiki the expectations vary from:
* gobble as usual (the current inconsistent behavior)
* gobble nothing
* gobble all (as an XML parser does)
* structured (an enhancement of the current behavior, with more control)
* indent controlled

Since implementing one/several of these would require a major parser overhaul, 
it has been postponed to the next major release of Velocity 2.0 (and if someone 
is found to lead the implementation and testing activities).

Currently you can use three tricks to structure your templates with structured 
output:

a) Using an $indent variable and avoid whitespaces in template (code to handle 
the $indent variable could be positioned in a macro), example:
#set($indent = "  ")
${indent}...
#set($indent = "$indent  ")## indent a bit more
${indent}...
#set($indent = $indent.substring(2)## outdent
${indent}...

b) Use block comments to avoid unwanted whitespaces at EOL, example:
  Size: $reader.available() (from class $reader.class.name)
  Contents:
#**##foreach( $char in [1..$reader.available()] )#*
    *##set( $int = $reader.read() )#*
    *##toASCII($int)#*
  *##end
#end

c) write code that does not emit stray whitepaces, example is an indent macro!:
#macro( indent $spaces $text )
#**##if( $text )
#*  *##set( $text = $text.trim() )
#**##else
#*  *##set( $text = "" )
#**##end
#**##set( $LF = $Context.formDecode("%0A") )
#**### first line indented by caller:
#**##set( $l_indent = "" )
#**##set( $l_useIndent = true )
#**##foreach( $l_line in $Context.tokenize($text, $LF) )
#*  *#$l_indent$l_line#if(false)#* suppress EOL *##end
#*  *##set( $l_index = $l_line.lastIndexOf('pre>') - 1 )
#*  *##if( $l_index >= 0 )
#*    *##if( $l_line.charAt($l_index).toString().equals('/') )
#*      *##set( $l_useIndent = true )
#*    *##elseif( $l_line.charAt($l_index).toString().equals('<') )
#*      *##set( $l_indent = "$LF" )
#*      *##set( $l_useIndent = false )
#*    *##end
#*  *##end
#*  *##if( $l_useIndent )
#*    *##set( $l_indent = "$LF$spaces" )
#*  *##end
#**##end
...
#indent("   " $multiLineText)
...

Hope this helps,
Christoph

Nitin Nahata wrote:
> Hi Velocity Users/Developers,
> 
> I am trying to use a velocity template through  Java to generate some XML.
> All works wonderfully except that the generated XML is not well formatted.
> It seems to have random white spaces before and after tags. So when looked
> in a text editor it is quite difficult (non-user friendly) to read/edit.
> 
> Could anyone suggest how to tidy up the generated XML? I am aware of JTidy,
> but is there any other solution?
> 
> Regards,
> Nitin
> 

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to