Search code examples
javascriptjqueryregexbbcode

Jquery detect commands/Custom BBcode


So I want to be able to detect what a user on my forums writes in a post and change it's CSS accordingly. For example,

[hl color:'yellow']example test[/hl]

should apply a hightlight to the text:

style="background-color: yellow"

I want the jQuery code to detect [hl color: if successful, save the value between the ' ' in a variable then test for the remaining ]. I then want it to apply style="background-color: " + var to the text after the ] and before the [/hl]

Thanks in advanced.

Current unworking code:

$('.post').each(function() {   
  if($(this:contains('[hl color:'))) {
    var txt = [I have no idea];
    $(select the text in between tags).attr('style', 'background-color:' + txt);
  }
});

Solution

  • Option 1: Use a library

    There are already plenty of JavaScript libraries that parse BBCode. This one looks promising, and is extensible so that you can add your own tags. You could also consider doing the parsing on the server side (in PHP or whatever you are using) using a library there (like jBBCode for PHP).

    Option 2: Do it yourself

    No actual jQuery is needed for this. Instead, for simple tags regex does the trick:

    function bbcodeToHTML(bbcode) {
      return bbcode.replace(
               /\[\s*hl\s*color\s*:\s*(.*?)\s*\](.*?)\[\s*\/\s*hl\s*\]/gi,
               '<span style="background-color:$1;">$2</span>'
             );
    }
    

    So what does this regex do?

    • \[\s*hl\s*color\s*:\s*: Literal [, then any number of whitespaces, then color, then any number of whitespaces, then literal :, then any number of whitespaces.
    • (.*?): Captures (as $1) any characters lazily. This means that it tries to match as few characters as possible.
    • \s*\]: Ends the opening tag.
    • (.*?): Same as above, but captures as $2
    • \[\s*\/\s*hl\s*\]: Ending tag, with any number of whitespaces thrown in.
    • g: Global flag. Replaces all matches and do not stop after first.
    • i: Case insensitive flat. Match both HL and hl.

    See it in action here.

    Replacing the content of forum posts

    Now you will need som jQuery. I will assume that the elements that contain forum posts in BBCode that you want replaced with HTML all have a class named post so that they can be identified. Then this code would do the job:

    //Itterate over all forum posts.
    jQuery('.post').each(function() {
    
        //Get a reference to the current post.
        currentPost = jQuery(this);
    
        //Get the content ant turn it into HTML.
        postHTML = bbcodeToHTML(currentPost.html());
    
        //Put the html into the post.
        currentPost.html(postHTML);
    
    });
    

    For more info on jQuery, you can always check out the documentation.