0

quick question, I have some markdown HTML content that I'd like to convert from double asterisks to bold.

the error i'm getting is: `Uncaught TypeError: Cannot call method 'replace' of null '

here's the jsfiddle: http://jsfiddle.net/fz5ZT/9/

here's the HTML:

<div class="comments">comment 1** is good**</div>
<div class="comments">comment 2**is bad**</div>

here's the JS:

function markdown(markdownable){

  var boldMatch = markdownable.match(/\*\*[A-Za-z0-9]+\*\*/gim), 
  boldReplace = boldMatch.replace(/\*\*[A-z0-9]+\*\*/gim, '<span style="font-  weight:bold;color:blue;">'+boldMatch+'</span>'),                   
  markdownable = markdownable.replace(boldMatch, boldReplace),    
  markdownable = markdownable.replace(/\*\*/gi, "");

  return markdownable;
}

$('.comments').each(function(){  
   var markdownable=$(this).html(), comments=markdown(markdownable);
});

if you might be able to help i'd greatly appreciate it,

thanks, tim

update thanks all! please see this for a working demo: http://jsfiddle.net/fz5ZT/30/

3
  • If the bold rexep doesn't match, "boldMatch" will be null. "null" has no (prototype) property "replace" to call - throwing the error. Commented Apr 19, 2012 at 17:18
  • thanks Bergi, but why is "boldMatch" null if I'm feeding it the variable mardownable which contains text with double asterisks? Shouldn't it match? Commented Apr 19, 2012 at 17:48
  • No, there is a whitespace in markdownable which is matched by neither of your regexps. Commented Apr 19, 2012 at 17:55

5 Answers 5

7
markdownable = markdownable.replace( /\*\*(.+?)\*\*/gm, '<strong>$1</strong>' );

However, instead of performing a half-hearted, well-intentioned, doomed-to-fail attempt at reinventing the wheel, why not just use an existing JavaScript Markdown library?

Edit: Here's a more robust regex that (like Markdown) requires there to be no whitespace right after the "open" or before the "close":

var bold = /\*\*(\S(.*?\S)?)\*\*/gm;
markdownable = markdownable.replace( bold, '<strong>$1</strong>' );
Sign up to request clarification or add additional context in comments.

5 Comments

See developer.mozilla.org/en/JavaScript/Guide/… — it refers to the text that was found and captured inside the 1st set of parentheses (as counted from the left by where the left parenthesis was seen).
thanks, great, I had seen that before but didn't know what it meant!
hi Phrogz, i realized this helps with the regex part but still doesn't answer why the replace method is null. There are 2 comments containing asterisks shouldn't the replace method have 2 strings to replace?
I don't know what you mean by "why the replace method is null". There are lots of other good comments and answers telling you why your previous code was broken. Read them for more insight on your old code. My single line above replaces all that nonsense, all four lines of your function.
hi all, please see this jsfiddle for a working demo: jsfiddle.net/fz5ZT/30
2

Your first regex match is ignoring the whitespace in the string. you need to add a space to your allowed character set, [ a-z0-9]; you don't need the the A-Z because of the i.

Also, match returns an array, so you need to get the first match, boldMatch[0] in order to access the string returned.

2 Comments

Also, you need to check if boldMatch found something. because if not, it is null (and not an empty string) - that's why you got the error.
hi yoavmatchulsky, but shouldn't boldMatch find something? There are 2 comments with asterisks.
1

May be you can take a look at the following solution :

Find text string using jQuery?

I believe you need to do do something very similar :

  $('*:contains("I am a simple string")').each(function(){
 if($(this).children().length < 1) 
      $(this).html( 
           $(this).text().replace(
                /"I am a simple string"/
                ,'<span containsStringImLookingFor="true">"I am a simple string"   </span>' 
           )  
       ) 
});

For making the element bold you need to use the addClass() once the replace has taken place.

Thanks

Comments

1
function markdown(markdownable) {

    var boldMatch = markdownable.match(/[\*]{2}( .+)?[\*]{2}/gim);
    if (boldMatch && (boldMatch = boldMatch[0])) {
        var boldReplace = boldMatch.replace(/[\*]{2}( .+)+?[\*]{2}/gim, '<span style="font-weight:bold;color:blue;">' + boldMatch + '</span>');
        markdownable = markdownable.replace(boldMatch, boldReplace);
        markdownable = markdownable.replace(/\*\*/gi, "");
    }
    return markdownable;
}

$('.comments').each(function() {

    var markdownable = $(this).html(),
        comments = markdown(markdownable);

    console.log(comments);
});​

this is by far not the best solution... however it is the 'fix' for your attempt. Hopefully you can learn something about where you went wrong.

11 Comments

Note that there's no reason to use [\*] instead of just \* in the regex. And why are you requiring a space at the start of the contents?
because it appears that was the requirement for the match. **bad ** good
Oh; I personally doubt that's what was meant, since that's not in the original regex, and the opposite of what Markdown requires. I thought "good" and "bad" were just indications of comments. But perhaps you're correct.
as for the [] i generally put them in place for readability... but yes you are right that is a personal thing.
yes.. and as you will ** see** this only works on specific cases.
|
1

You don't want to call .replace() on boldMatch until you know that there is a value in there to work with, that is, if there was no match.

Safer computing:

var boldMatch = markdownable.match(/\*\*[A-Za-z0-9]+\*\*/gim);
if (boldMatch) { 
  var boldReplace = boldMatch.replace(/\*\*[A-z0-9]+\*\*/gim, '<span style="font- weight:bold;color:blue;">'+boldMatch+'</span>');
}

etc.

Update:

This line of code also makes it difficult to trace what's going on:

var markdownable=$(this).html(), comments=markdown(markdownable);

Declaring two variables on one line with var is generally frowned on. Better:

var markdownable=$(this).html();
if (markdownable) {
    comments=markdown(markdownable);
}

2 Comments

hi David, thanks for your response, but shouldn't boldMatch find something? There are 2 comments with asterisks.
As Bergi mentioned, the first one of your test cases won't match. Try this as a test case and you might see what's going on: <div class="comments"></div>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.