views:

62

answers:

2

Is it possible, using Javascript and either jQuery or regular expressions, to group multiple sibling list items in HTML as in the example below? I need to convert TikiWiki markup to HTML, and it uses ungrouped lists (just adjacent lines appended with #).

<li>Item 1.1</li>
<li>Item 1.2</li>
<li>Item 1.3</li>
<p>Paragraph</p>
<li>Item 2.1</li>
<li>Item 2.2</li>

To this:

<ul>
<li>Item 1.1</li>
<li>Item 1.2</li>
<li>Item 1.3</li>
</ul>
<p>Paragraph</p>
<ul>
<li>Item 2.1</li>
<li>Item 2.2</li>
</ul>

I already tried using $("li").wrapAll() and siblings(). Both failed.

There's another approach. Here's the regex I'm currently using to convert TikiWiki lists to HTML list items: replace(/[#](.*)\n?/g, "<li class='numbered'>$1</li>") Is it possible to match repeated patterns, and convert them accordingly to HTML as in this pseudo regex? replace(/repeat([#](.*)\n?)/g, "<ol>foreach(<li class='numbered'>$1</li>)</ol>")

A: 

Here is my first hack at it. this might get you going in the right direction

    <div id='testList'>
        <li>Item 1.1</li>
        <li>Item 1.2</li>
        <li>Item 1.3</li>
        <p>Paragraph</p>
        <li>Item 2.1</li>
        <li>Item 2.2</li>

    </div>

<script language='javascript' type='text/javascript'>

$.fn.tagName = function() {
    return this.get(0).tagName;
}

$(document).ready(function() {

    alert($("#testList").html());

    $("li").each(function() {
        if ( $(this).parent().tagName() != "UL" ) {
            $(this).wrap("<ul></ul>");
            // alert($(this).parent().tagName())
        }
    })

    alert($("#testList").html());
});
</script>
Sage
BTW - this effectively wrapped each li element in a separate UL
Sage
A: 

The <p> is just hanging out in the middle of a bunch of <li>s, signifying the beginning or end of a group? Then maybe something like this:

​$('div#container') // assume you're got it in a container div
  .find('p').each( function(){ // each p signifies a new group
    $(this)
      .prev('li') // walk back to the preceding li
      .prevUntil('p') // get the set of elements up to the previous p
      .andSelf() // include the current li
      .wrapAll('<ul>');​​​​​​​​​​​​​​​​​​​​​​​​​​ // wrap the set in a ul
   });

​ Here's a working jsFiddle using this approach.

Ken Redler
No, it was just an example. There could by anything in the middle, or maybe even nothing at all (just one list).
Propeng
Okay, then could you post an example of the text you're working on?
Ken Redler
@Ken, nice approach!
Sage
@Ken It's processing input from a textarea, so there's really no static text.
Propeng