Skip to content
Advertisement

Preventing orphaned words but exclude tag

I’m using the answer from this question to prevent orphaned words by inserting   between the last two word within paragraphs and headings.

As the author states, it doesn’t work when the last word is inside the <a> tag.

So

<p>Call us at <a href="tel:+18001234567">1-800-123-4567</a></p>

renders as

<p>Call us at <a&nbsp;href="tel:+18001234567">1-800-123-4567</a&nbsp;href="tel:+18001234567"></p>

Can this be fixed so that it ignores any content inside html tags?

Advertisement

Answer

Here’s a solution taken from this post and adapted to rebuilding your html. Note that regex gets a little iffy-er the more complex and nested your html. However, works like a charm here! The post link explains the regex in detail.

$("p,h1,h2,h3,h4,h5,h6").each(function() {
  result = $(this).html().match(/<s*(w+b)(?:(?!<s*/s*1b)[sS])*<s*/s*1s*>|S+/g);
  let out = "";
  result.forEach(function(seg, index){
    let sep;
    if (index == result.length - 1) sep = "";
    else if (index == result.length - 2) sep = "&nbsp;";
    else sep = " ";
    out += seg + sep;
  })
  $(this).html(out);
  console.log($(this).prop('outerHTML'))
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<p>Call us at <a href="tel:+18001234567">1-800-123-4567</a></p>

In case it helps troubleshooting the gulp issue, here is a minified version

$("p,h1,h2,h3,h4,h5,h6").each(function(){result=$(this).html().match(/<s*(w+b)(?:(?!<s*/s*1b)[sS])*<s*/s*1s*>|S+/g);let t="";result.forEach(function(h,s){let l;l=s==result.length-1?"":s==result.length-2?"&nbsp;":" ",t+=h+l}),$(this).html(t),console.log($(this).prop("outerHTML"))});
Advertisement