Marc Novakowski wrote:
Yeah, we use the ## trick in a few macros where removal of whitespace is critical. In most templates, extra whitespace isn't a big deal since, in the end, it's all gobbled into a single whitespace character by the HTML parser. It's just when you look at the HTML source, it's ugly!

Also, the "##" trick only works to remove newlines, but the indentation whitespace (i.e. tabs or spaces) before the velocity statement on the line will still be there.

In (my) ideal world, the following:

<table>
    <tr>
        #if ($foo == "bar")
            <td>Fred</td>
        #else
            <td>Bob</td>
        #end
    </tr>
</table>


Would result in:

<table>
    <tr>
            <td>Fred</td>
    </tr>
</table>

But what is wrong with just providing a custom filter writer to the 
mergeTemplate
method?  It seems to me that you can create any whitespace policy you want this 
way.
Or better yet -- a chained filter writer.  One that deals with spaces and maybe 
another
that deals with eols.  I put an example of this on this list a long time ago -- 
here
it is again.  These writers can be greatly improved but they worked for us.

James

Marc


On 21-Nov-06, at 9:56 AM, Will Glass-Husain wrote:

Hi Marc,

Thanks for the input.  There seems to be widespread dissatisfaction
with the status quo on this issue, yet it's a tricky issue to change
while maintaining backwards compatibility (involves fundamental
changes to the parser).  Currently thinking about this as part of some
future 2.0 version.

Incidentally, the best solution for leaving out extra newlines is to
put "##" at the end of each line.  This kills the newline.  Doesn't
help the issue of extra spaces before indented statements, though.

WILL

On 11/21/06, Marc Novakowski <[EMAIL PROTECTED]> wrote:
I've been meaning to add my vote to this page, so I finally did it.
+1 for gobbling structured templates.

We use velocity for most of the "backstage" area at Pandora.  It's
made development so much easier!  However, the final HTML looks quite
messy due to all of the extra whitespace introduced by the velocity
templates.

Marc

On 14-Nov-06, at 8:18 AM, [EMAIL PROTECTED] wrote:

> See the Wiki on this issue:
>   http://wiki.apache.org/jakarta-velocity/VelocityWhitespaceGobbling
>
> Please add your opinion (well thought out) or vote for one of the
> presented approaches.
>
> Cheers,
> Christoph
>
> Paul Loy wrote:
>> I would be very interested in a solution to this problem. From a code
>> layout point of view this would be an important feature. Consider:
>>
>> <div>
>>    &quot;
>>
>> #if ($somevar)
>>    $somevar
>> #else
>>    nothing here
>> #end
>>
>>    &quot;
>> </div>
>>
>> This nicely formatted code makes it easy to see what's going on
>> but will
>> make the html render with spaces in it like so (if $somevar is
>> false or
>> null):
>>
>> ' nothing here '
>>
>> Now this is a silly example and in this case it would be much
>> easier to
>> simply do this to eliminate the problem:
>>
>>
>> <div>
>>
>> #if ($somevar)
>>    &quot;$somevar&quot;
>> #else
>>    &quot;nothing here&quot;
>> #end
>>
>> </div>
>>
>> but in more complex examples you'd either have a great amount of
>> duplicated HTML, which makes it bad to maintain and update, or you'd
>> have to make unreadable code (everything on one line with no white
>> spaces).
>>
>> I converted an old nasty taglibbed jsp into velocity and although I
>> cleaned up the html (removing 20+ unnecessary nested tables) the
>> filesize of the velocity version was actually slightly bigger than
>> the
>> old version because of all the whitespace.
>>
>> So... I would very much like velocity to perhaps remove whitespace
>> between a directive (i.e. a # statement) and any other code.
>>
>> Paul.
>>
>> Timothy Stone wrote:
>>> List,
>>>
>>> We noticed in #parse'ing an .vm file, excess whitespace, or
>>> linefeeds,
>>> are appearing in our templates after merge.
>>>
>>> For example, where a '+' indicates a line feed or carriage return:
>>>
>>> [mystyles.vm]
>>> +
>>> #set( $foo = "Copyright (c)")
>>> +
>>> #set( $bar = "2006" )
>>> +
>>>
>>>
>>> [myemail.txt]
>>> #parse("mystyles.vm")
>>> +
>>> Dear bloated warthog,
>>> blah
>>> +
>>> blah
>>> +
>>> blah
>>> +
>>> Regards,
>>> Man in Black
>>> +
>>> ${foo} ${bar}
>>>
>>> [The final output]
>>> +
>>> +
>>> +
>>> +
>>> Dear bloated warthog,
>>> blah
>>> +
>>> blah
>>> +
>>> blah
>>> +
>>> Regards,
>>> Man in Black
>>> +
>>> Copyright (c) 2006
>>>
>>> Can these extra lines be managed in some way?
>>>
>>> Thanks,
>>> Tim



--
 James Wilson
 Developer
 U.S. District Court
 District of New Mexico
 333 Lomas Blvd., NW
 Albuquerque, NM 87102
 Phone: (505) 348-2081
 Fax: (505) 348-2028
 [EMAIL PROTECTED]
--
/*
** This file is provided by the
** U.S. Courts, District of New Mexico - www.nmcourt.fed.us.
**
** Software Developers <[EMAIL PROTECTED]>
**
** $Author: james $
** $Date: 2005/07/30 17:57:57 $
** $Revision: 1.1 $
** $Id: DoubleSpaceFilterWriter.java,v 1.1 2005/07/30 17:57:57 james Exp $
*/

package us.fed.nmcourt.deuce.common.io;

import java.io.IOException;
import java.io.FilterWriter;
import java.io.Writer;
import java.lang.ref.SoftReference;
import java.util.Arrays;

public class DoubleSpaceFilterWriter extends FilterWriter
{
    private static final int BUFFER_SIZE = 1024;
    private static final char CHAR_NULL  = '\0';
    private static final char CHAR_SPACE = ' ';

    private char cPrevChar = CHAR_NULL;
    private char cNextChar = CHAR_NULL;

    private char[] cWorkBuffer = null;

    public DoubleSpaceFilterWriter(Writer writer)
    {
        super(writer);
    }

    public void close()
        throws IOException
    {
        out.close();
    }

    public void flush()
        throws IOException
    {
        out.flush();
    }

    public void write(int c)
        throws IOException
    {
        synchronized (lock)
        {
            initWorkBuffer();

            cWorkBuffer[0] = (char) c;

            write(cWorkBuffer, 0, 1);
        }
    }

    public void write(char[] buffer, int offset, int length)
        throws IOException
    {
        synchronized (lock)
        {
            if (!(length > 0))
            {
                return;
            }

            int newIndex     = -1;
            char[] newBuffer = new char[length];
            int newLength    = 0;

            try
            {
                int bufferIndex = offset;
                int bufferLength = offset + length;
                while (bufferIndex < bufferLength)
                {
                    cNextChar = buffer[bufferIndex++];

                    if ((cPrevChar != CHAR_SPACE) ||
                        (cPrevChar == CHAR_SPACE && cNextChar != CHAR_SPACE))
                    {
                        newBuffer[++newIndex] = cNextChar;
                        newLength = (newIndex + 1);
                    }

                    cPrevChar = cNextChar;
                }

                if (newLength > 0)
                {
                    out.write(newBuffer, 0, newLength);
                }
            }
            finally
            {
                newBuffer = null;
            }
        }
    }

    public void write(String string, int offset, int length)
        throws IOException
    {
        synchronized (lock)
        {
            if (!(length > 0))
            {
                return;
            }

            initWorkBuffer();

            char[] buffer = null;
            if (length > BUFFER_SIZE)
            {
                buffer = new char[length];
            }
            else
            {
                buffer = cWorkBuffer;
            }

            try
            {
                string.getChars(offset, (offset + length), buffer, 0);

                write(buffer, 0, length);
            }
            finally
            {
                buffer = null;
            }
        }
    }

    protected void finalize()
        throws Throwable
    {
        if (cWorkBuffer != null)
        {
            SoftReference softReference = new SoftReference(cWorkBuffer);
            softReference = null;
            cWorkBuffer = null;
        }

        super.finalize();
    }

    private void initWorkBuffer()
    {
        if (cWorkBuffer == null)
        {
            cWorkBuffer = new char[BUFFER_SIZE];
        }
        else
        {
            Arrays.fill(cWorkBuffer, CHAR_NULL);
        }
    }
}
/*
** This file is provided by the
** U.S. Courts, District of New Mexico - www.nmcourt.fed.us.
**
** Software Developers <[EMAIL PROTECTED]>
**
** $Author: james $
** $Date: 2005/07/30 17:57:57 $
** $Revision: 1.1 $
** $Id: DoubleNewlineFilterWriter.java,v 1.1 2005/07/30 17:57:57 james Exp $
*/

package us.fed.nmcourt.deuce.common.io;

import java.io.LineNumberReader;
import java.io.IOException;
import java.io.FilterWriter;
import java.io.StringReader;
import java.io.Writer;
import java.lang.ref.SoftReference;
import java.util.Arrays;

public class DoubleNewlineFilterWriter extends FilterWriter
{
    private static final char[] CRLF     = new char[] {'\r', '\n'};
    private static final int BUFFER_SIZE = 1024;

    private char[] cWorkBuffer = null;

    public DoubleNewlineFilterWriter(Writer writer)
    {
        super(writer);
    }

    public void close()
        throws IOException
    {
        out.close();
    }

    public void flush()
        throws IOException
    {
        out.flush();
    }

    public void write(int c)
        throws IOException
    {
        synchronized (lock)
        {
            initWorkBuffer();

            cWorkBuffer[0] = (char) c;

            write(cWorkBuffer, 0, 1);
        }
    }

    public void write(char[] buffer, int offset, int length)
        throws IOException
    {
        synchronized (lock)
        {
            if (!(length > 0))
            {
                return;
            }

            StringReader stringReader = new StringReader(
                    new String(buffer, offset, length));

            LineNumberReader lineReader = new LineNumberReader(stringReader);

            try
            {
                String line = null;
                while ((line = lineReader.readLine()) != null)
                {
                    if (line.length() > 0)
                    {
                        char[] writeBuffer = line.toCharArray();
                        out.write(writeBuffer, 0, writeBuffer.length);
                        out.write(CRLF, 0, CRLF.length);
                        writeBuffer = null;
                    }
                    line = null;
                }
            }
            finally
            {
                try
                {
                    stringReader.close();
                }
                catch (Exception e)
                {
                }
                stringReader = null;

                try
                {
                    lineReader.close();
                }
                catch (Exception e)
                {
                }
                lineReader = null;
            }
        }
    }

    public void write(String string, int offset, int length)
        throws IOException
    {
        synchronized (lock)
        {
            if (!(length > 0))
            {
                return;
            }

            initWorkBuffer();

            char[] buffer = null;
            if (length > BUFFER_SIZE)
            {
                buffer = new char[length];
            }
            else
            {
                buffer = cWorkBuffer;
            }

            try
            {
                string.getChars(offset, (offset + length), buffer, 0);

                write(buffer, 0, length);
            }
            finally
            {
                buffer = null;
            }
        }
    }

    protected void finalize()
        throws Throwable
    {
        if (cWorkBuffer != null)
        {
            SoftReference softReference = new SoftReference(cWorkBuffer);
            softReference = null;
            cWorkBuffer = null;
        }

        super.finalize();
    }

    private void initWorkBuffer()
    {
        if (cWorkBuffer == null)
        {
            cWorkBuffer = new char[BUFFER_SIZE];
        }
        else
        {
            Arrays.fill(cWorkBuffer, '\0');
        }
    }
}
/*
** This file is provided by the
** U.S. Courts, District of New Mexico - www.nmcourt.fed.us.
**
** Software Developers <[EMAIL PROTECTED]>
**
** $Author: james $
** $Date: 2005/07/30 17:57:57 $
** $Revision: 1.1 $
** $Id: StripTabFilterWriter.java,v 1.1 2005/07/30 17:57:57 james Exp $
*/

package us.fed.nmcourt.deuce.common.io;

import java.io.IOException;
import java.io.FilterWriter;
import java.io.Writer;
import java.lang.ref.SoftReference;
import java.util.Arrays;

public class StripTabFilterWriter extends FilterWriter
{
    private static final int BUFFER_SIZE = 1024;
    private static final char CHAR_NULL  = '\0';
    private static final char CHAR_TAB   = '\t';

    private char[] cWorkBuffer = null;

    public StripTabFilterWriter(Writer writer)
    {
        super(writer);
    }

    public void close()
        throws IOException
    {
        out.close();
    }

    public void flush()
        throws IOException
    {
        out.flush();
    }

    public void write(int c)
        throws IOException
    {
        synchronized (lock)
        {
            initWorkBuffer();

            cWorkBuffer[0] = (char) c;

            write(cWorkBuffer, 0, 1);
        }
    }

    public void write(char[] buffer, int offset, int length)
        throws IOException
    {
        synchronized (lock)
        {
            if (!(length > 0))
            {
                return;
            }

            int newIndex     = -1;
            char[] newBuffer = new char[length];
            int newLength    = 0;

            try
            {
                char nextChar   = CHAR_NULL;
                int bufferIndex = offset;
                int bufferLength = offset + length;
                while (bufferIndex < bufferLength)
                {
                    nextChar = buffer[bufferIndex++];

                    if (nextChar != CHAR_TAB)
                    {
                        newBuffer[++newIndex] = nextChar;
                        newLength = (newIndex + 1);
                    }
                }

                if (newLength > 0)
                {
                    out.write(newBuffer, 0, newLength);
                }
            }
            finally
            {
                newBuffer = null;
            }
        }
    }

    public void write(String string, int offset, int length)
        throws IOException
    {
        synchronized (lock)
        {
            if (!(length > 0))
            {
                return;
            }

            initWorkBuffer();

            char[] buffer = null;
            if (length > BUFFER_SIZE)
            {
                buffer = new char[length];
            }
            else
            {
                buffer = cWorkBuffer;
            }

            try
            {
                string.getChars(offset, (offset + length), buffer, 0);

                write(buffer, 0, length);
            }
            finally
            {
                buffer = null;
            }
        }
    }

    protected void finalize()
        throws Throwable
    {
        if (cWorkBuffer != null)
        {
            SoftReference softReference = new SoftReference(cWorkBuffer);
            softReference = null;
            cWorkBuffer = null;
        }

        super.finalize();
    }

    private void initWorkBuffer()
    {
        if (cWorkBuffer == null)
        {
            cWorkBuffer = new char[BUFFER_SIZE];
        }
        else
        {
            Arrays.fill(cWorkBuffer, CHAR_NULL);
        }
    }
}

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to