Search code examples
javascriptregextinymce

Restricting the Number of Blank Lines in TinyMCE Editor


I am working with TinyMCE in JavaScript and facing a challenge in implementing a restriction on the number of blank lines users can input. The goal is to allow a maximum of two empty lines before and after any text within the TinyMCE editor, regardless of whether the user pressed Enter (creating <p> blocks) or used Shift + Enter (creating <br> elements).

I have successfully handled cases involving three or more <br> elements and empty <p> tags using regular expressions like:

//replace 4 and more <br> for 3 <br>
var updatedContent = content.replace(/((<br\s*\/?>\s*){4,})/gm, '<br><br><br>');

//Similar approach for 3 or more EMPTY <p> tags - replace for 2 

3 <br> elements after some text creates 2 blank lines, meanwhile 3 empty <p> tags creates 3 lines. However, if 3 <br> elements are right after opening <p> tag it creates also 3 lines:

<p><br><br><br>sometext<br><br><br></p> //-> 3 empty lines before sometext but 2 after.

this is easy to handle as well. I am looking if there is more then 2 <br> elements after opening <p> tag and replace them with exactly 2..

Btw: tinymce puts everything inside <p> tags, so if I try to replace empty <p></p> for <br> it creates <p><br><p> which is same as <p></p> and tinymce automaticaly convert it to this form, so I am unable to get rid of them.

but I'm struggling with scenarios like:

<p>text<br><br></p>
<p><br><br></p>
<p>Before this text, there are three blank lines; the allowed maximum is two<br><br></p>
<p><br><br>Text with three blank lines before</p>
<p></p>
<p></p>
<p><br><br>This is text with four blank lines before<br></p>
<p> "<br>" right in front of "</p>" doesn't have any effect on blank lines</p>
<p><br><br></p>
<p></p>
<p>Before this text, there are three blank lines; the allowed maximum is two<br></p>

I've attempted various regular expressions, but none seem to cover all cases correctly. Could someone provide insights or a solution on how to handle these scenarios and limit the number of blank lines to a maximum of two before and after any text within the TinyMCE editor? If there is any easier way to do this in tinymce just let me know.


Solution

  • So after several attempts, hours of struggling, cursing, and desperation, I believe I have successfully captured all possible variations of occurrences of two lines. Here is the code:

        //replace 4 and more <br> for 3 <br>
        var updatedContent = content.replace(/((<br\s*\/?>\s*){4,})/gm, '<br><br><br>');
    
        //replace <p> followed by 3 or more <br> with <p> and 2 <br>
        updatedContent = updatedContent.replace(/<p>\s*(<br\s*\/?>\s*){3,}/gm, '<p><br><br>');
        
        //replace 4 or more <br> followed by </p> with 3 <br> and </p>
        updatedContent = updatedContent.replace(/(<br\s*\/?>\s*){3,}\s*<\/p>/gm, '<br><br><br></p>');
        
        //replace 2 or more consecutive occurrences of <p> (any number of <br>) </p>  with <p></p><p></p>
        updatedContent = updatedContent.replace(/(<p>\s*(<br\s*\/?>\s*)*<\/p>\s*){2,}/g, '<p></p><p></p>');
        
        //replace <br><br><br></p><p>empty or <br>s</p> with <br><br><br></p>
        updatedContent = updatedContent.replace(/<br\s*\/?>\s*<br\s*\/?>\s*<br\s*\/?>\s*<\/p>(\s*<p>\s*(<br\s*\/?>\s*)*\s*<\/p>\s*)*/gm, '<br><br><br></p>');
        
        //replace <br><br></p><p>empty or <br></p> with <br><br></p><p></p>
        updatedContent = updatedContent.replace(/<br\s*\/?>\s*<br\s*\/?>\s*<\/p>(\s*<p>\s*(<br\s*\/?>\s*)*\s*<\/p>\s*)+/gm, '<br><br></p><p></p>');
        
        //replace <br><br><br></p><p>empty or <br> with <br><br><br></p><p>
        updatedContent = updatedContent.replace(/<br\s*\/?>\s*<br\s*\/?>\s*<br\s*\/?>\s*<\/p>\s*<p>\s*(<br\s*\/?>\s*)+/gm, '<br><br><br></p><p>');
    
        //replace <br><br></p><p>empty or <br> with <br><br></p><p><br>
        updatedContent = updatedContent.replace(/<br\s*\/?>\s*<br\s*\/?>\s*<\/p>\s*<p>\s*(<br\s*\/?>\s*)+/gm, '<br><br></p><p><br>');
        
        //replace 2 or more consecutive occurrences of <p> (any number of <br>) </p> followed by <p> and any number of <br>  with <p></p><p></p><p>
        updatedContent = updatedContent.replace(/(<p>\s*(<br\s*\/?>\s*)*<\/p>\s*){2,}<p>\s*(<br\s*\/?>\s*)+/gm, '<p></p><p></p><p>');
                
        //replace <br><br><p></p><p> any number of <br> with <br><br></p><p></p><p>
        updatedContent = updatedContent.replace(/<br\s*\/?>\s*<br\s*\/?><\/p>\s*<p>\s*<\/p>\s*<p>\s*(<br\s*\/?>\s*)+/gm, '<br><br></p><p></p><p>');
    
        //replace 2 or more consecutive occurrences of <p> (any number of <br>) </p>  with <p></p><p></p>
        updatedContent = updatedContent.replace(/(<p>\s*(<br\s*\/?>\s*)*<\/p>\s*){1,}<p>\s*(<br\s*\/?>\s*)+/gm, '<p></p><p><br>');