Is There An Easy Way To Convert Html With Multiple
Tags Into Proper Surrounding
Tags In Javascript?
Solution 1:
I got bored. I'm sure there are optimizations / tweaks needed. Uses a little bit of jQuery to do its magic. Worked in FF3. And the answer to your question is that there isnt a very "simple" way :)
$(function() {
$.fn.pmaker = function() {
var brs = 0;
var nodes = [];
functionmakeP()
{
// only bother doing this if we have nodes to stick into a Pif (nodes.length) {
var p = $("<p/>");
p.insertBefore(nodes[0]); // insert a new P before the content
p.append(nodes); // add the children
nodes = [];
}
brs=0;
}
this.contents().each(function() {
if (this.nodeType == 3) // text node
{
// if the text has non whitespace - reset the BR counterif (/\S+/.test(this.data)) {
nodes.push(this);
brs = 0;
}
} elseif (this.nodeType == 1) {
if (/br/i.test(this.tagName)) {
if (++brs == 2) {
$(this).remove(); // remove this BR from the dom
$(nodes.pop()).remove(); // delete the previous BR from the array and the DOMmakeP();
} else {
nodes.push(this);
}
} elseif (/^(?:p)$/i.test(this.tagName)) {
// these tags for the P break but dont scan withinmakeP();
} elseif (/^(?:div)$/i.test(this.tagName)) {
// force a P break and scan withinmakeP();
$(this).pmaker();
} else {
brs = 0; // some other tag - reset brs.
nodes.push(this); // add the node // specific nodes to not peek inside of - inline tagsif (!(/^(?:b|i|strong|em|span|u)$/i.test(this.tagName))) {
$(this).pmaker(); // peek inside for P needs
}
}
}
});
while ((brs--)>0) { // remove any extra BR's at the end
$(nodes.pop()).remove();
}
makeP();
returnthis;
};
// run it against something:
$(function(){
$("#worker").pmaker();
});
And this was the html portion I tested against:
<divid="worker">
bla bla bla long <b>paragraph</b> here
<br/><br/>
bla bla bla more paragraph text
<br/><br/>
this text should end up in a P
<divclass='test'>
and so should this
<br/><br/>
and this<br/>without breaking at the single BR
</div>
and then we have the a "buggy" clause
<p>
fear the real P!
</p>
and a trailing br<br/></div>
And the result:
<divid="worker"><p>
bla bla bla long <b>paragraph</b> here
</p><p>
bla bla bla more paragraph text
</p><p>
this text should end up in a P
</p><divclass="test"><p>
and so should this
</p><p>
and this<br/>without breaking at the single BR
</p></div><p>
and then we have the a "buggy" clause
</p><p>
fear the real P!
</p><p>
and a trailing br</p></div>
Solution 2:
Scan each of the child elements + text of the enclosing element. Each time you encounter a "br" element, create a "p" element, and append all pending stuff to it. Lather, rinse, repeat.
Don't forget to remove the stuff which you are relocating to a new "p" element.
I have found this library (prototype.js) to be useful for this sort of thing.
Solution 3:
I'm assuming you're not really allowing any other
Sometimes you need to preserve single line-breaks (not all <br />
elements are bad), and you only want to turn double instances of <br />
into paragraph breaks.
In doing so I would:
- Remove all line breaks
- Wrap the whole lot in a paragraph
- Replace
<br /><br />
with</p>\n<p>
- Lastly, remove any empty
<p></p>
elements that might have been generated
So the code could look something like:
varConvertToParagraphs = function(text) {
var lineBreaksRemoved = text.replace(/\n/g, "");
var wrappedInParagraphs = "<p>" + lineBreaksRemoved + "</p>";
var brsRemoved = wrappedInParagraphs.replace(/<br[^>]*>[\s]*<br[^>]*>/gi, "</p>\n<p>");
var emptyParagraphsRemoved = brsRemoved.replace(/<p><\/p>/g, "");
return emptyParagraphsRemoved;
}
Note: I've been exceedingly verbose to show the processes, you'd simplify it of course.
This turns your sample:
bla bla bla long paragraph here
<br/><br/>
bla bla bla more paragraph text
<br/><br/>
Into:
<p>bla bla bla long paragraph here</p>
<p>bla bla bla more paragraph text</p>
But it does so without removing any <br />
elements that you may actually want.
Solution 4:
I'd do it in several stages:
- RegExp: Convert all br-tags to line-breaks.
- RegExp: Strip out all the white-space.
- RegExp: Convert the multiple line-breaks to single ones.
- Use Array.split('\n') on the result.
That should give an array with all the 'real' paragraphs (in theory.) Then you can just iterate through it and wrap each line in p-tags.
Post a Comment for "Is There An Easy Way To Convert Html With Multiple
Tags Into Proper Surrounding
Tags In Javascript?"