Genshi: for loop inserts line breaks

205 views Asked by At

Source code: I have the following program.

import genshi
from genshi.template import MarkupTemplate

html = '''
    <html xmlns="http://www.w3.org/1999/xhtml" xmlns:py="http://genshi.edgewall.org/">
        <head>
        </head>
        <body>
            <py:for each="i in range(3)">
                <py:choose>
                    <del py:when="i == 1">
                        ${i}
                    </del>
                    <py:otherwise>
                        ${i}
                    </py:otherwise>
                </py:choose>
            </py:for>
        </body>
    </html>
'''

template = MarkupTemplate(html)
stream = template.generate()
html = stream.render('html')

print(html)

Expected output: the numbers are printed consecutively with no whitespace (and most critically no line-break) between them.

<html>
    <head>
    </head>
    <body>
            0<del>1</del>2
    </body>
</html>

Actual output: It outputs the following:

<html>
    <head>
    </head>
    <body>
            0
            <del>1</del>
            2
    </body>
</html>

Question: How do I eliminate the line-breaks? I can deal with the leading whitespace by stripping it from the final HTML, but I don't know how to get rid of the line-breaks. I need the contents of the for loop to be displayed as a single continuous "word" (e.g. 012 instead of 0 \n 1 \n 2).

What I've tried:

  • Reading the Genshi documentation.
  • Searching StackOverflow
  • Searching Google
  • Using a <?python ...code... ?> code block. This doesn't work since the carets in the <del> tags are escaped and displayed.

    <?python
        def numbers():
            n = ''
            for i in range(3):
                if i == 1:
                    n += '<del>{i}</del>'.format(i=i)
                else:
                    n += str(i)
            return n
    ?>
    ${numbers()}
    

    Produces 0&lt;del&gt;1&lt;/del&gt;2 I also tried this, but using genshi.builder.Element('del') instead. The results are the same, and I was able to conclusively determine that the string returned by numbers() is being escaped after the return occurs.

  • A bunch of other things that I can't recall at the moment.

1

There are 1 answers

0
ErikusMaximus On BEST ANSWER

Not ideal, but I did finally find an acceptable solution. The trick is to put the closing caret for a given tag on the next line right before the next tag's opening caret.

<body>
    <py:for each="i in range(3)"
        ><py:choose
            ><del py:when="i == 1">${i}</del
            ><py:otherwise>${i}</py:otherwise
        ></py:choose
    </py:for>
</body>

Source: https://css-tricks.com/fighting-the-space-between-inline-block-elements/

If anyone has a better approach I'd love to hear it.