views:

40

answers:

3

Hey all! I got an HTML string that I need to parse (to be used in Flash), by wrapping nested UL tags by a span with incremented left-margin value based on nesting level.

Before:

<ul>
    <li>Item one</li>
    <li>Item two:
        <ul>
            <li>One</li>
            <li>Two
                <ul>
                    <li>One</li>
                    <li>Two</li>
                </ul>
            </li>
        </ul>
    </li>
    <li>Item three
        <ul>
            <li>One</li>
            <li>Two</li>
        </ul>
    </li>
    <li>Item four</li>
</ul>

After:

<span style="left-margin:0px">
    <ul>
        <li>Item one</li>
        <li>Item two:
            <span style="left-margin:30px">
                <ul>
                    <li>One</li>
                    <li>Two
                        <span style="left-margin:60px">
                            <ul>
                                <li>One</li>
                                <li>Two</li>
                            </ul>
                        </span>
                    </li>
                </ul>
            </span>
        </li>
        <li>Item three
            <span style="left-margin:30px">
                <ul>
                    <li>One</li>
                    <li>Two</li>
                </ul>
            </span>
        </li>
        <li>Item four</li>
    </ul>
</span>

Note the incremented value: 0, 30, 60...

I did a (nasty) ActionScript solution, but I think there must be some elegant way to do it.

A: 

Since they are nested the margins should not have to be incremented.. each one starts from its nest level so it would add to the current margin ..

Putting left-margin:30px; to all span should do it ..

Not sure if you have other CSS definitions that might interfere with that,though.. so please elaborate..

Gaby
I need to increment the margin, since I'll be using it in a Flash text field, which doesn't render HTML the same way a browser does.
Makram Saleh
A: 

Maybe like this. Put the nested list in some container element and run this on that container element:

function recursiveIndentation(element, indentation, increasingIndentation) {
    for (var i = 0; i < element.childNodes.length; i = i + 1) {
        if (element.childNodes[i].nodeName === "UL") {
            var span = document.createElement("SPAN");
            span.style.marginLeft = indentation + "px";
            element.insertBefore(span, element.childNodes[i])
            span.appendChild(element.childNodes[i + 1]);
            recursiveIndentation(span.childNodes[0], indentation + increasingIndentation, increasingIndentation);
        } else {
            recursiveIndentation(element.childNodes[i], indentation, increasingIndentation);
        }
    }
}

The innerHtml attribute of your container element will now hold the string you need.

Oscar Kilhed
A: 

For a CSS-only solution:

ul { margin-left: 0 }
ul ul { margin-left: 30px }
ul ul ul { margin-left: 60px }
ul ul ul ul { margin-left: 90px }

Not pretty/generic/what you asked for, but it's at least very simple and may be good enough.

Wim
Since this will be used in flash, there's no way I can use CSS like the above.
Makram Saleh