- Get all the
<br>
nodes. Optionally, ignore the ones directly
inside a <p>
block.
- Then, for each
<br>
node, wrap any text nodes that immediately precede or immediately follow it.
- Finally, delete the
<br>
node.
This approach handles nesting and doesn't trash links, the page layout, etc.
The code:
$('.your_cms_container br').each ( function () {
if (this.parentNode.nodeName != "P") {
$.each ([this.previousSibling, this.nextSibling], function () {
if (this.nodeType === 3) { // 3 == text
$(this).wrap ('<p></p>');
}
} );
$(this).remove (); //-- Kill the <br>
}
} );
Update:
After editing the OP's question, I realized that I hadn't quite addressed his specific situation. (I use the above code, to great effect in userscripts.)
He wants to change this:
<p> "Paragraph 1" <br />
<a href="http://xkcd.com/246/">Link, the first</a>
Line after single break.
<br /><br />
"Paragraph 2"
</p>
into this:
<p> "Paragraph 1" <br />
<a href="http://xkcd.com/246/">Link, the first</a>
Line after single break.
</p>
<p> "Paragraph 2" </p>
The difficulties being: You don't want to trash nested elements (if any) or event handlers (if any).
For this, use the following approach:
- Grab just the offending paragraphs with a selector like
p:has(br+br)
. Beware that the adjacent selector ignores text nodes -- the very thing we don't want it to do, in this case.
- Loop through each offending paragraph's contents, one by one.
- Use a state machine to create a new paragraph at each
<br><br>
and to move the content nodes to the appropriate <p>
.
The code looks like this. You can see it in action at jsFiddle:
var badGraphs = $("#content p:has(br+br)");
var targetP = null;
var justSplit = false;
badGraphs.each ( function () {
var parentP = $(this);
parentP.contents ().each ( function (J) {
if (justSplit) {
justSplit = false;
// Continue the loop. Otherwise, it would copy an unwanted <br>.
return true;
}
var thisjNode = $(this);
var nextjNode = $(this.nextSibling);
if (thisjNode.is ("br") && nextjNode.is ("br") ) {
thisjNode.remove (); //-- Kill this <br>
nextjNode.remove (); //-- and the next
//-- Create a new p for any following content
targetP = targetP || parentP;
targetP.after ('<p></p>');
targetP = targetP.next ("p");
justSplit = true;
}
else if (targetP) {
//-- Move the node to its new home.
targetP.append (this);
}
} );
} );