From fe5ce67ef8a12b24ac02fdfc84ff186bb5d8371a Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Sun, 4 Mar 2018 17:34:59 -0500 Subject: [PATCH] Move bb2diaspora() content to Content\Text\BBCode::toMarkdown - Use self where appropriate - Add BaseObject extension --- include/bb2diaspora.php | 182 +--------------------------------- src/Content/Text/BBCode.php | 168 +++++++++++++++++++++++++++++-- src/Content/Text/Markdown.php | 2 +- 3 files changed, 160 insertions(+), 192 deletions(-) diff --git a/include/bb2diaspora.php b/include/bb2diaspora.php index 7f942be14..932d543db 100644 --- a/include/bb2diaspora.php +++ b/include/bb2diaspora.php @@ -2,191 +2,11 @@ use Friendica\Content\Text\BBCode; use Friendica\Content\Text\Markdown; -use Friendica\Core\Addon; -use Friendica\Core\L10n; -use Friendica\Core\System; -use Friendica\Model\Contact; -use Friendica\Network\Probe; -use Friendica\Util\DateTimeFormat; -use League\HTMLToMarkdown\HtmlConverter; - -require_once 'include/event.php'; -require_once 'include/html2bbcode.php'; function diaspora2bb($s) { return Markdown::toBBCode($s); } -/** - * @brief Callback function to replace a Friendica style mention in a mention for Diaspora - * - * @param array $match Matching values for the callback - * @return string Replaced mention - */ -function diaspora_mentions($match) { - - $contact = Contact::getDetailsByURL($match[3]); - - if (!x($contact, 'addr')) { - $contact = Probe::uri($match[3]); - } - - if (!x($contact, 'addr')) { - return $match[0]; - } - - $mention = '@{' . $match[2] . '; ' . $contact['addr'] . '}'; - return $mention; -} - -/** - * @brief Converts a BBCode text into Markdown - * - * This function converts a BBCode item body to be sent to Markdown-enabled - * systems like Diaspora and Libertree - * - * @param string $Text - * @param bool $fordiaspora Diaspora requires more changes than Libertree - * @return string - */ function bb2diaspora($Text, $fordiaspora = true) { - $a = get_app(); - - $OriginalText = $Text; - - // Since Diaspora is creating a summary for links, this function removes them before posting - if ($fordiaspora) { - $Text = BBCode::removeShareInformation($Text); - } - - /** - * Transform #tags, strip off the [url] and replace spaces with underscore - */ - $URLSearchString = "^\[\]"; - $Text = preg_replace_callback("/#\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/i", - function ($matches) { - return '#' . str_replace(' ', '_', $matches[2]); - } - , $Text); - - // Converting images with size parameters to simple images. Markdown doesn't know it. - $Text = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '[img]$3[/img]', $Text); - - // Extracting multi-line code blocks before the whitespace processing/code highlighter in BBCode::convert() - $codeblocks = []; - - $Text = preg_replace_callback("#\[code(?:=([^\]]*))?\](.*?)\[\/code\]#is", - function ($matches) use (&$codeblocks) { - $return = $matches[0]; - if (strpos($matches[2], "\n") !== false) { - $return = '#codeblock-' . count($codeblocks) . '#'; - - $prefix = '````' . $matches[1] . PHP_EOL; - $codeblocks[] = $prefix . trim($matches[2]) . PHP_EOL . '````'; - } - return $return; - } - , $Text); - - // Convert it to HTML - don't try oembed - if ($fordiaspora) { - $Text = BBCode::convert($Text, false, 3); - - // Add all tags that maybe were removed - if (preg_match_all("/#\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", $OriginalText, $tags)) { - $tagline = ""; - foreach ($tags[2] as $tag) { - $tag = html_entity_decode($tag, ENT_QUOTES, 'UTF-8'); - if (!strpos(html_entity_decode($Text, ENT_QUOTES, 'UTF-8'), '#' . $tag)) { - $tagline .= '#' . $tag . ' '; - } - } - $Text = $Text." ".$tagline; - } - } else { - $Text = BBCode::convert($Text, false, 4); - } - - // mask some special HTML chars from conversation to markdown - $Text = str_replace(['<', '>', '&'], ['&_lt_;', '&_gt_;', '&_amp_;'], $Text); - - // If a link is followed by a quote then there should be a newline before it - // Maybe we should make this newline at every time before a quote. - $Text = str_replace(["
"], ["
"], $Text); - - $stamp1 = microtime(true); - - // Now convert HTML to Markdown - $converter = new HtmlConverter(); - $Text = $converter->convert($Text); - - // unmask the special chars back to HTML - $Text = str_replace(['&\_lt\_;', '&\_gt\_;', '&\_amp\_;'], ['<', '>', '&'], $Text); - - $a->save_timestamp($stamp1, "parser"); - - // Libertree has a problem with escaped hashtags. - $Text = str_replace(['\#'], ['#'], $Text); - - // Remove any leading or trailing whitespace, as this will mess up - // the Diaspora signature verification and cause the item to disappear - $Text = trim($Text); - - if ($fordiaspora) { - $URLSearchString = "^\[\]"; - $Text = preg_replace_callback("/([@]\[(.*?)\])\(([$URLSearchString]*?)\)/ism", 'diaspora_mentions', $Text); - } - - // Restore code blocks - $Text = preg_replace_callback('/#codeblock-([0-9]+)#/iU', - function ($matches) use ($codeblocks) { - $return = ''; - if (isset($codeblocks[intval($matches[1])])) { - $return = $codeblocks[$matches[1]]; - } - return $return; - } - , $Text); - - Addon::callHooks('bb2diaspora',$Text); - - return $Text; -} - -function unescape_underscores_in_links($m) { - $y = str_replace('\\_', '_', $m[2]); - return('[' . $m[1] . '](' . $y . ')'); -} - -function format_event_diaspora($ev) { - if (! ((is_array($ev)) && count($ev))) { - return ''; - } - - $bd_format = L10n::t('l F d, Y \@ g:i A') ; // Friday January 18, 2011 @ 8 AM - - $o = 'Friendica event notification:' . "\n"; - - $o .= '**' . (($ev['summary']) ? bb2diaspora($ev['summary']) : bb2diaspora($ev['desc'])) . '**' . "\n"; - - // @todo What. Is. Going. On. With. This. Useless. Ternary. Operator? - mrpetovan - $o .= L10n::t('Starts:') . ' ' . '[' . day_translate( - $ev['adjust'] ? DateTimeFormat::utc($ev['start'], $bd_format) : DateTimeFormat::utc($ev['start'], $bd_format) - ) - . '](' . System::baseUrl() . '/localtime/?f=&time=' . urlencode(DateTimeFormat::utc($ev['start'])) . ")\n"; - - if (! $ev['nofinish']) { - $o .= L10n::t('Finishes:') . ' ' . '[' . day_translate( - $ev['adjust'] ? DateTimeFormat::utc($ev['finish'], $bd_format) : DateTimeFormat::utc($ev['finish'], $bd_format) - ) - . '](' . System::baseUrl() . '/localtime/?f=&time=' . urlencode(DateTimeFormat::utc($ev['finish'])) . ")\n"; - } - - if (strlen($ev['location'])) { - $o .= L10n::t('Location:') . bb2diaspora($ev['location']) - . "\n"; - } - - $o .= "\n"; - return $o; + return BBCode::toMarkdown($Text, $fordiaspora); } diff --git a/src/Content/Text/BBCode.php b/src/Content/Text/BBCode.php index 8dd9305ca..9c7dac260 100644 --- a/src/Content/Text/BBCode.php +++ b/src/Content/Text/BBCode.php @@ -1,33 +1,37 @@ %s
', trim(BBCode::convert($data["description"]))); + $return .= sprintf('
%s
', trim(self::convert($data["description"]))); } if ($data["type"] == "link") { @@ -1202,7 +1206,7 @@ class BBCode $text = Cache::get($match[1]); if (is_null($text)) { - $a = get_app(); + $a = self::getApp(); $stamp1 = microtime(true); @@ -1261,7 +1265,7 @@ class BBCode $text = Cache::get($match[1]); if (is_null($text)) { - $a = get_app(); + $a = self::getApp(); $stamp1 = microtime(true); @@ -1285,7 +1289,7 @@ class BBCode $doc = new DOMDocument(); @$doc->loadHTML($body); - $xpath = new DomXPath($doc); + $xpath = new DOMXPath($doc); $list = $xpath->query("//meta[@name]"); foreach ($list as $node) { $attr = []; @@ -1348,7 +1352,7 @@ class BBCode */ public static function convert($text, $try_oembed = true, $simple_html = false, $for_plaintext = false) { - $a = get_app(); + $a = self::getApp(); /* * preg_match_callback function to replace potential Oembed tags with Oembed content @@ -1978,4 +1982,148 @@ class BBCode return $abstract; } + + /** + * @brief Callback function to replace a Friendica style mention in a mention for Diaspora + * + * @param array $match Matching values for the callback + * @return string Replaced mention + */ + private static function bbCodeMention2DiasporaCallback($match) + { + $contact = Contact::getDetailsByURL($match[3]); + + if (empty($contact['addr'])) { + $contact = Probe::uri($match[3]); + } + + if (empty($contact['addr'])) { + return $match[0]; + } + + $mention = '@{' . $match[2] . '; ' . $contact['addr'] . '}'; + return $mention; + } + + /** + * @brief Converts a BBCode text into Markdown + * + * This function converts a BBCode item body to be sent to Markdown-enabled + * systems like Diaspora and Libertree + * + * @param string $text + * @param bool $for_diaspora Diaspora requires more changes than Libertree + * @return string + */ + public static function toMarkdown($text, $for_diaspora = true) + { + $a = self::getApp(); + + $original_text = $text; + + // Since Diaspora is creating a summary for links, this function removes them before posting + if ($for_diaspora) { + $text = self::removeShareInformation($text); + } + + /** + * Transform #tags, strip off the [url] and replace spaces with underscore + */ + $url_search_string = "^\[\]"; + $text = preg_replace_callback("/#\[url\=([$url_search_string]*)\](.*?)\[\/url\]/i", + function ($matches) { + return '#' . str_replace(' ', '_', $matches[2]); + }, + $text + ); + + // Converting images with size parameters to simple images. Markdown doesn't know it. + $text = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '[img]$3[/img]', $text); + + // Extracting multi-line code blocks before the whitespace processing/code highlighter in self::convert() + $codeblocks = []; + + $text = preg_replace_callback("#\[code(?:=([^\]]*))?\](.*?)\[\/code\]#is", + function ($matches) use (&$codeblocks) { + $return = $matches[0]; + if (strpos($matches[2], "\n") !== false) { + $return = '#codeblock-' . count($codeblocks) . '#'; + + $prefix = '````' . $matches[1] . PHP_EOL; + $codeblocks[] = $prefix . trim($matches[2]) . PHP_EOL . '````'; + } + return $return; + }, + $text + ); + + // Convert it to HTML - don't try oembed + if ($for_diaspora) { + $text = self::convert($text, false, 3); + + // Add all tags that maybe were removed + if (preg_match_all("/#\[url\=([$url_search_string]*)\](.*?)\[\/url\]/ism", $original_text, $tags)) { + $tagline = ""; + foreach ($tags[2] as $tag) { + $tag = html_entity_decode($tag, ENT_QUOTES, 'UTF-8'); + if (!strpos(html_entity_decode($text, ENT_QUOTES, 'UTF-8'), '#' . $tag)) { + $tagline .= '#' . $tag . ' '; + } + } + $text = $text . " " . $tagline; + } + } else { + $text = self::convert($text, false, 4); + } + + // mask some special HTML chars from conversation to markdown + $text = str_replace(['<', '>', '&'], ['&_lt_;', '&_gt_;', '&_amp_;'], $text); + + // If a link is followed by a quote then there should be a newline before it + // Maybe we should make this newline at every time before a quote. + $text = str_replace(["
"], ["
"], $text); + + $stamp1 = microtime(true); + + // Now convert HTML to Markdown + $converter = new HtmlConverter(); + $text = $converter->convert($text); + + // unmask the special chars back to HTML + $text = str_replace(['&\_lt\_;', '&\_gt\_;', '&\_amp\_;'], ['<', '>', '&'], $text); + + $a->save_timestamp($stamp1, "parser"); + + // Libertree has a problem with escaped hashtags. + $text = str_replace(['\#'], ['#'], $text); + + // Remove any leading or trailing whitespace, as this will mess up + // the Diaspora signature verification and cause the item to disappear + $text = trim($text); + + if ($for_diaspora) { + $url_search_string = "^\[\]"; + $text = preg_replace_callback( + "/([@]\[(.*?)\])\(([$url_search_string]*?)\)/ism", + ['self', 'bbCodeMention2DiasporaCallback'], + $text + ); + } + + // Restore code blocks + $text = preg_replace_callback('/#codeblock-([0-9]+)#/iU', + function ($matches) use ($codeblocks) { + $return = ''; + if (isset($codeblocks[intval($matches[1])])) { + $return = $codeblocks[$matches[1]]; + } + return $return; + }, + $text + ); + + Addon::callHooks('bb2diaspora', $text); + + return $text; + } } diff --git a/src/Content/Text/Markdown.php b/src/Content/Text/Markdown.php index 0e6846ebf..e7383a3fd 100644 --- a/src/Content/Text/Markdown.php +++ b/src/Content/Text/Markdown.php @@ -87,7 +87,7 @@ class Markdown extends BaseObject // Escaping the hash tags $s = preg_replace('/\#([^\s\#])/', '#$1', $s); - $s = Markdown::convert($s); + $s = self::convert($s); $regexp = "/@\{(?:([^\}]+?); )?([^\} ]+)\}/"; $s = preg_replace_callback($regexp, ['self', 'diasporaMention2BBCodeCallback'], $s);