I found the answer by karim79 useful. I modified it a bit, so I want to share my version. Maybe it will help someone out there.
I modified the answer to adapt it from JavaScript to PHP (I know the question doesn't have a PHP tag)
I also changed from while()
to for()
because:
- I didn't want to replace uninterrupted sequences of asterisks like "********"
- I didn't want to remove unpaired "*"
It's still not perfect, it will for example "strongify" anything between two far apart *'s, consuming both of them. But I think this is how whatsapp behaves also.
I assume there are better ways of forcing the end of the loop than what I did, I just followed the rule "if it aint broken, don't fix it". I'm happy to receive suggestions
function md2html($text = "") {
// I constantly check for length of text, instead of assigning the value to a var (which would be more efficient) because the length changes with every replacement!
for ($i = 0; $i < strlen($text); $i++) {
if (($beg = strpos($text,"*",$i)) !== FALSE){
if (($seq = strspn($text,"*",$beg)) > 1)
$i = $beg + $seq; // skip sequence
else {
if (($end = strpos($text,"*",$beg + 1)) !== FALSE){ // found a second one
$length = $end - $beg - 1;
$innerText = substr($text,$beg+1,$length);
$strongified = "<strong>$innerText</strong>";
// following the original answer I should do something like
// $text = substr($text,0,$beg) . $strongified . substr($text,$end+1);
// but I assume the following is better:
$text = substr_replace($text,$strongified,$beg,$length+2); // adding to length to include both asterisks
$i = $end + 16; // the real position in the string has now increased due to replacement
} else
$i = strlen($text); // force end of for loop
}
} else
$i = strlen($text);
}
for ($i = 0; $i < strlen($text); $i++) {
if (($beg = strpos($text,"_",$i)) !== FALSE){
if (($seq = strspn($text,"_",$beg)) > 1)
$i = $beg + $seq;
else {
if (($end = strpos($text,"_",$beg + 1)) !== FALSE){
$length = $end - $beg - 1;
$innerText = substr($text,$beg+1,$length);
$italicized = "<em>$innerText</em>";
$text = substr_replace($text,$italicized,$beg,$length+2);
$i = $end + 10;
} else
$i = strlen($text);
}
} else
$i = strlen($text);
}
return $text;
}