array('open' => $start_open, 'close' => $start_close),
'end' => array('open' => $end_open, 'close' => $end_open + strlen('[/' . $name . ']')) );
if( $start_equal !== false)
$res['start']['equal'] = $start_equal + 1;
return $res;
}
function bb_tag_preg_replace($pattern, $replace, $name, $s) {
$string = $s;
$occurance = 1;
$pos = get_bb_tag_pos($string, $name, $occurance);
while($pos !== false && $occurance < 1000) {
$start = substr($string, 0, $pos['start']['open']);
$subject = substr($string, $pos['start']['open'], $pos['end']['close'] - $pos['start']['open']);
$end = substr($string, $pos['end']['close']);
if($end === false)
$end = '';
$subject = preg_replace($pattern, $replace, $subject);
$string = $start . $subject . $end;
$occurance++;
$pos = get_bb_tag_pos($string, $name, $occurance);
}
return $string;
}
function tryoembed($match) {
$url = ((count($match) == 2) ? $match[1] : $match[2]);
$o = oembed_fetch_url($url);
if ($o['type'] == 'error')
return $match[0];
$html = oembed_format_object($o);
return $html;
}
function nakedoembed($match) {
$url = ((count($match) == 2) ? $match[1] : $match[2]);
$strip_url = strip_escaped_zids($url);
// this function no longer performs oembed on naked links
// because they author may have created naked links intentionally.
// Now it just strips zids on naked links.
return str_replace($url,$strip_url,$match[0]);
}
function tryzrlaudio($match) {
$link = $match[1];
$zrl = is_matrix_url($link);
if($zrl)
$link = zid($link);
return '';
}
function tryzrlvideo($match) {
$link = $match[1];
$zrl = is_matrix_url($link);
if($zrl)
$link = zid($link);
$static_link = get_config('system','video_default_poster','images/video_poster.jpg');
if($static_link)
$poster = 'poster="' . escape_tags($static_link) . '" ' ;
return '';
}
function videowithopts($match) {
$link = $match[2];
$zrl = is_matrix_url($link);
if($zrl)
$link = zid($link);
$attributes = $match[1];
$poster = "";
preg_match("/poster='(.*?)'/ism", $attributes, $matches);
if ($matches[1] != "")
$poster = 'poster="' . (($zrl) ? zid($matches[1]) : $matches[1]) . '"';
preg_match("/poster=\"\;(.*?)\"\;/ism", $attributes, $matches);
if ($matches[1] != "")
$poster = 'poster="' . (($zrl) ? zid($matches[1]) : $matches[1]) . '"';
preg_match("/poster=\\\"(.*?)\\\"/ism", $attributes, $matches);
if ($matches[1] != "")
$poster = 'poster="' . (($zrl) ? zid($matches[1]) : $matches[1]) . '"';
return '';
}
// [noparse][i]italic[/i][/noparse] turns into
// [noparse][ i ]italic[ /i ][/noparse],
// to hide them from parser.
function bb_spacefy($st) {
$whole_match = $st[0];
$captured = $st[1];
$spacefied = preg_replace("/\[(.*?)\]/", "[ $1 ]", $captured);
$new_str = str_replace($captured, $spacefied, $whole_match);
return $new_str;
}
// The previously spacefied [noparse][ i ]italic[ /i ][/noparse],
// now turns back and the [noparse] tags are trimmed
// returning [i]italic[/i]
function bb_unspacefy_and_trim($st) {
//$whole_match = $st[0];
$captured = $st[1];
$unspacefied = preg_replace("/\[ (.*?)\ ]/", "[$1]", $captured);
return $unspacefied;
}
function bb_extract_images($body) {
$saved_image = array();
$orig_body = $body;
$new_body = '';
$cnt = 0;
$img_start = strpos($orig_body, '[img');
$img_st_close = ($img_start !== false ? strpos(substr($orig_body, $img_start), ']') : false);
$img_end = ($img_start !== false ? strpos(substr($orig_body, $img_start), '[/img]') : false);
while(($img_st_close !== false) && ($img_end !== false)) {
$img_st_close++; // make it point to AFTER the closing bracket
$img_end += $img_start;
if(! strcmp(substr($orig_body, $img_start + $img_st_close, 5), 'data:')) {
// This is an embedded image
$saved_image[$cnt] = substr($orig_body, $img_start + $img_st_close, $img_end - ($img_start + $img_st_close));
$new_body = $new_body . substr($orig_body, 0, $img_start) . '[$#saved_image' . $cnt . '#$]';
$cnt++;
}
else
$new_body = $new_body . substr($orig_body, 0, $img_end + strlen('[/img]'));
$orig_body = substr($orig_body, $img_end + strlen('[/img]'));
if($orig_body === false) // in case the body ends on a closing image tag
$orig_body = '';
$img_start = strpos($orig_body, '[img');
$img_st_close = ($img_start !== false ? strpos(substr($orig_body, $img_start), ']') : false);
$img_end = ($img_start !== false ? strpos(substr($orig_body, $img_start), '[/img]') : false);
}
$new_body = $new_body . $orig_body;
return array('body' => $new_body, 'images' => $saved_image);
}
function bb_replace_images($body, $images) {
$newbody = $body;
$cnt = 0;
if(! $images)
return $newbody;
foreach($images as $image) {
// We're depending on the property of 'foreach' (specified on the PHP website) that
// it loops over the array starting from the first element and going sequentially
// to the last element
$newbody = str_replace('[$#saved_image' . $cnt . '#$]', '', $newbody);
$cnt++;
}
// logger('replace_images: ' . $newbody);
return $newbody;
}
/**
* @brief Parses crypt BBCode.
*
* @param array $match
* @return string HTML code
*/
function bb_parse_crypt($match) {
$matches = [];
$attributes = $match[1];
$algorithm = "";
preg_match("/alg='(.*?)'/ism", $attributes, $matches);
if ($matches[1] != "")
$algorithm = $matches[1];
preg_match("/alg=\"\;(.*?)\"\;/ism", $attributes, $matches);
if ($matches[1] != "")
$algorithm = $matches[1];
preg_match("/alg=\\\"(.*?)\\\"/ism", $attributes, $matches);
if ($matches[1] != "")
$algorithm = $matches[1];
$hint = "";
$matches = [];
preg_match("/hint='(.*?)'/ism", $attributes, $matches);
if ($matches[1] != "")
$hint = $matches[1];
preg_match("/hint=\"\;(.*?)\"\;/ism", $attributes, $matches);
if ($matches[1] != "")
$hint = $matches[1];
preg_match("/hint=\\\"(.*?)\\\"/ism", $attributes, $matches);
if ($matches[1] != "")
$hint = $matches[1];
$x = random_string();
$f = 'hz_decrypt';
$onclick = 'onclick="' . $f . '(\'' . $algorithm . '\',\'' . $hint . '\',\'' . $match[2] . '\',\'#' . $x . '\');"';
$label = t('Encrypted content');
$Text = '
' . bb_code_protect(trim($match[1])) . '
';
else
return '' . bb_code_protect(trim($match[1])) . '
';
}
function bb_code_options($match) {
if(strpos($match[0], "' . bb_code_protect(trim($match[2])) . '
';
} else {
return '' . bb_code_protect(trim($match[2])) . '
';
}
}
function md_header($content) {
$headingLevel = \strlen($content[1]);
$header = trim($content[2]);
// Build anker without space, numbers.
$anker = preg_replace('#[^a-z?!]#', '', strtolower($header));
return sprintf('%s
', $class, bb_code_protect($content));
}
function md_italic($content) {
return '' . $content[1] . $content[3] . '';
}
function md_image($content) {
$url = filter_var($content[1], FILTER_SANITIZE_URL);
$alt = '';
if (isset($content[2])) {
$content[2] = str_replace('"', '', $content[2]);
$alt = ' alt="' . filter_var($content[2], FILTER_SANITIZE_STRING) . '"';
}
return sprintf('', $url, $alt);
}
function md_topheader($matches) {
// Terrible hack to check we haven't found an empty list item.
if ($matches[2] == '-' && preg_match('{^-(?: |$)}', $matches[1])) {
return $matches[0];
}
$level = $matches[2][0] == '=' ? 1 : 2;
return "$1'; // Check for [quote] text // handle nested quotes $endlessloop = 0; while ((strpos($Text, "[/quote]") !== false) && (strpos($Text, "[quote]") !== false) && (++$endlessloop < 20)) $Text = preg_replace("/\[quote\](.*?)\[\/quote\]/ism", "$QuoteLayout", $Text); // Check for [quote=Author] text $t_wrote = t('$1 wrote:'); // handle nested quotes $endlessloop = 0; while ((strpos($Text, "[/quote]")!== false) && (strpos($Text, "[quote=") !== false) && (++$endlessloop < 20)) $Text = preg_replace("/\[quote=[\"\']*(.*?)[\"\']*\](.*?)\[\/quote\]/ism", "" . $t_wrote . "
$2", $Text); if ($plain) { $Text = str_replace([ '
','' ], [ '“', '”' ], $Text); } // Images // [img]pathtoimage[/img] if (strpos($Text,'[/img]') !== false) { $Text = preg_replace("/\[img\](.*?)\[\/img\]/ism", '', $Text); // Friendica's modified bbcode img tags $Text = preg_replace("/\[img=http(.*?)\](.*?)\[\/img\]/ism", '', $Text); } if (strpos($Text,'[/zmg]') !== false) { $Text = preg_replace("/\[zmg\](.*?)\[\/zmg\]/ism", '', $Text); } $Text = preg_replace_callback("/\[([zi])mg([ \=])(.*?)\](.*?)\[\/[zi]mg\]/ism",'bb_imgoptions',$Text); if($censored) { $Text = separate_img_links($Text); $Text = preg_replace_callback("/\/ism","bb_colorbox",$Text); } // style (sanitized) if (strpos($Text,'[/style]') !== false) { $Text = preg_replace_callback("(\[style=(.*?)\](.*?)\[\/style\])ism", "bb_sanitize_style", $Text); } // crypt if (strpos($Text,'[/crypt]') !== false) { if ($activitypub) { $Text = preg_replace_callback("/\[crypt (.*?)\](.*?)\[\/crypt\]/ism", 'bb_parse_b64_crypt', $Text); } else { $Text = preg_replace_callback("/\[crypt (.*?)\](.*?)\[\/crypt\]/ism", 'bb_parse_crypt', $Text); } } if (strpos($Text,'[/app]') !== false) { if ($activitypub) { $Text = preg_replace_callback("/\[app\](.*?)\[\/app\]/ism",'bb_parse_app_ap', $Text); } else { $Text = preg_replace_callback("/\[app\](.*?)\[\/app\]/ism",'bb_parse_app', $Text); } } if(strpos($Text,'[/element]') !== false) { $Text = preg_replace_callback("/\[element\](.*?)\[\/element\]/ism",'bb_parse_element', $Text); } // html5 video and audio if (strpos($Text,'[/video]') !== false) { $Text = preg_replace_callback("/\[video (.*?)\](.*?)\[\/video\]/ism", 'videowithopts', $Text); $Text = preg_replace_callback("/\[video\](.*?)\[\/video\]/ism", 'tryzrlvideo', $Text); } if (strpos($Text,'[/audio]') !== false) { $Text = preg_replace_callback("/\[audio\](.*?)\[\/audio\]/ism", 'tryzrlaudio', $Text); } if (strpos($Text,'[/zvideo]') !== false) { $Text = preg_replace_callback("/\[zvideo (.*?)\](.*?)\[\/zvideo\]/ism", 'videowithopts', $Text); $Text = preg_replace_callback("/\[zvideo\](.*?)\[\/zvideo\]/ism", 'tryzrlvideo', $Text); } if (strpos($Text,'[/zaudio]') !== false) { $Text = preg_replace_callback("/\[zaudio\](.*?)\[\/zaudio\]/ism", 'tryzrlaudio', $Text); } // if video couldn't be embedded, link to it instead. if (strpos($Text,'[/video]') !== false) { $Text = preg_replace("/\[video\](.*?)\[\/video\]/", '$1', $Text); } if (strpos($Text,'[/audio]') !== false) { $Text = preg_replace("/\[audio\](.*?)\[\/audio\]/", '$1', $Text); } if (strpos($Text,'[/zvideo]') !== false) { $Text = preg_replace("/\[zvideo\](.*?)\[\/zvideo\]/", '$1', $Text); } if (strpos($Text,'[/zaudio]') !== false) { $Text = preg_replace("/\[zaudio\](.*?)\[\/zaudio\]/", '$1', $Text); } // SVG stuff if ($activitypub) { $Text = preg_replace_callback("/\[svg(.*?)\](.*?)\[\/svg\]/ism", 'bb_svg_export', $Text); } else { $Text = preg_replace_callback("/\[svg(.*?)\](.*?)\[\/svg\]/ism", 'bb_svg', $Text); } // oembed tag if(! $export) $Text = oembed_bbcode2html($Text); // Avoid triple linefeeds through oembed $Text = str_replace("