src/includes/classes/Core/Utils/Slack.php
public function mrkdwn($value, array $args = [])
    {
        if (is_array($value) || is_object($value)) {
            foreach ($value as $_key => &$_value) {
                $_value = $this->mrkdwn($_value, $args);
            } // unset($_key, $_value);
            return $value;
        }
        $markdown = (string) $value;

        if (!isset($markdown[0])) {
            return $markdown;
        }
        $default_args = [
            'current_gfm_owner' => '',
            'current_gfm_repo'  => '',
            'is_gfm'            => false,
        ];
        $args += $default_args; // Merge defaults.

        $is_gfm            = (bool) $args['is_gfm'];
        $current_gfm_owner = (string) $args['current_gfm_owner'];
        $current_gfm_repo  = (string) $args['current_gfm_repo'];

        // GitHub flavored markdown?
        if ($is_gfm) { // If so, convert issue references.
            $markdown = $this->c::mdGitHubIssueRefs($markdown, [
                'current_owner' => $current_gfm_owner,
                'current_repo'  => $current_gfm_repo,
            ]); // Keeps MD formatting.
        } // Converts MD issue references.

        // Begin conversions.
        $mrkdwn = $markdown; // Converting.

        // Normalize breaks for `/m` mode below.
        $mrkdwn = $this->c::normalizeEols($mrkdwn);

        // Remove language specifier from MD fences.
        $mrkdwn = preg_replace('/^(\h*)(~{3,}|`{3,})[\w\-]+(\v)/uim', '$1$2$3', $mrkdwn);

        // Tokenize; i.e., strip MD fences.
        $Tokenizer = $this->c::tokenize($mrkdwn, ['md-fences']);
        $mrkdwn    = &$Tokenizer->getString(); // By reference.

        // Convert markdown `*italic*` into Slack `_italic_`.
        $mrkdwn = preg_replace('/(?<=^|[\s;,(])\*{1}([^*\v]+)\*{1}(?=$|[\s.!?;,)])/ui', '_$1_', $mrkdwn);

        // Convert markdown `**bold**` into Slack `*bold*`.
        $mrkdwn = preg_replace('/(?<=^|[\s;,(])\*{2}([^*\v]+)\*{2}(?=$|[\s.!?;,)])/ui', '*$1*', $mrkdwn);

        // Convert markdown `~~strike~~` into Slack `~strike~`.
        $mrkdwn = preg_replace('/(?<=^|[\s;,(])~{2}([^~\v]+)~{2}(?=$|[\s.!?;,)])/ui', '~$1~', $mrkdwn);

        // Convert markdown headings into Slack `*bold*`.
        $mrkdwn = preg_replace('/^([ ]*)(#+)[ ]+([^#\v]+?)(?:[ ]+\\2)?(?:[ ]+\{[^{}]*\})?$/uim', '$1*$3*', $mrkdwn);

        // Convert markdown list items into Slack `:li:`.
        $mrkdwn = preg_replace_callback('/^([ ]*)[*\-][ ]+(?!\[)/uim', function ($m) {
            return str_replace(' ', '   ', $m[1]).':li:'; // Via emoji code.
        }, $mrkdwn); // This turns each space into 3 for nested list items.

        // Convert markdown list items into Slack `- :cbc:` or `- :cb:`.
        $mrkdwn = preg_replace_callback('/^([ ]*)[*\-][ ]+\[([x| ])\](?=[ ]+)/uim', function ($m) {
            return str_replace(' ', '   ', $m[1]).($m['2'] === 'x' ? ':cbc:' : ':cb:');
        }, $mrkdwn); // This turns each space into 3 for nested list items.

        // Tokenize  markdown `<>` links because `<>` are escaped below. Note UTF-8 `⟨` and `⟩` in place of `<` and `>`.
        $mrkdwn = preg_replace('/(?<=^|[\s;,(])\<([a-z][a-z0-9+.\-]*\:[^\s<>]+)\>(?=$|[\s.!?;,)])/ui', '⟨$1⟩', $mrkdwn);

        // Escape special HTML chars. Converts `<>&` into plain text; i.e., disallows raw HTML code.
        $mrkdwn = $this->c::escHtmlChars($mrkdwn); // After `<>` links & issue references.

        // Restore  markdown `<>` links. Note UTF-8 `⟨` and `⟩` in place of `<` and `>`.
        $mrkdwn = preg_replace('/(?<=^|[\s;,(])[⟨]([a-z][a-z0-9+.\-]*\:[^\s<>]+)[⟩](?=$|[\s.!?;,)])/ui', '<$1>', $mrkdwn);

        // Replace images (not Slack compatible) with clickable links.
        $mrkdwn = preg_replace_callback('/\!?\[(?:[^[\]]*|(?R))\]\([a-z][a-z0-9+.\-]*\:[^\s()]+\)(?:[ ]+\{[^{}]*\})?/ui', function ($m) {
            if (mb_stripos($m[0], '![') === false) {
                return $m[0]; // Not an image.
            } else {
                return preg_replace_callback('/\!\[(?<alt_text>[^[\]]*)\]\((?<url>[a-z][a-z0-9+.\-]*\:[^\s()]+)\)/ui', function ($m) {
                    return '<'.$m['url'].'|'.$this->c::escHtmlChars($m['alt_text'] ? $m['alt_text'].' '.__('(image)') : $this->c::midClip(basename($m['url']), 15)).'>';
                }, $m[0]); // Strip away images.
            }
        }, $mrkdwn); // Strip away images.

        // Convert links for Slack compatibility.
        $mrkdwn = preg_replace_callback('/(?<=^|[\s;,(])\[(?<text>[^|[\]]*)\]\((?<url>[a-z][a-z0-9+.\-]*\:[^|\s()]+)\)(?=$|[\s.!?;,)])/ui', function ($m) {
            if (isset($m['text'][0])) {
                return '<'.$m['url'].'|'.$this->c::escHtmlChars($m['text']).'>';
            } else {
                return '<'.$m['url'].'>';
            }
        }, $mrkdwn); // `<url|text>`

        // No more than two consecutive breaks.
        $mrkdwn = $this->c::mbTrim($this->c::normalizeEols($mrkdwn, true));

        return $mrkdwn = &$Tokenizer->restoreGetString();
    }
public function mrkdwn($value, array $args = [])
    {
        if (is_array($value) || is_object($value)) {
            foreach ($value as $_key => &$_value) {
                $_value = $this->mrkdwn($_value, $args);
            } // unset($_key, $_value);
            return $value;
        }
        $markdown = (string) $value;

        if (!isset($markdown[0])) {
            return $markdown;
        }
        $default_args = [
            'current_gfm_owner' => '',
            'current_gfm_repo'  => '',
            'is_gfm'            => false,
        ];
        $args += $default_args; // Merge defaults.

        $is_gfm            = (bool) $args['is_gfm'];
        $current_gfm_owner = (string) $args['current_gfm_owner'];
        $current_gfm_repo  = (string) $args['current_gfm_repo'];

        // GitHub flavored markdown?
        if ($is_gfm) { // If so, convert issue references.
            $markdown = $this->c::mdGitHubIssueRefs($markdown, [
                'current_owner' => $current_gfm_owner,
                'current_repo'  => $current_gfm_repo,
            ]); // Keeps MD formatting.
        } // Converts MD issue references.

        // Begin conversions.
        $mrkdwn = $markdown; // Converting.

        // Normalize breaks for `/m` mode below.
        $mrkdwn = $this->c::normalizeEols($mrkdwn);

        // Remove language specifier from MD fences.
        $mrkdwn = preg_replace('/^(\h*)(~{3,}|`{3,})[\w\-]+(\v)/uim', '$1$2$3', $mrkdwn);

        // Tokenize; i.e., strip MD fences.
        $Tokenizer = $this->c::tokenize($mrkdwn, ['md-fences']);
        $mrkdwn    = &$Tokenizer->getString(); // By reference.

        // Convert markdown `*italic*` into Slack `_italic_`.
        $mrkdwn = preg_replace('/(?<=^|[\s;,(])\*{1}([^*\v]+)\*{1}(?=$|[\s.!?;,)])/ui', '_$1_', $mrkdwn);

        // Convert markdown `**bold**` into Slack `*bold*`.
        $mrkdwn = preg_replace('/(?<=^|[\s;,(])\*{2}([^*\v]+)\*{2}(?=$|[\s.!?;,)])/ui', '*$1*', $mrkdwn);

        // Convert markdown `~~strike~~` into Slack `~strike~`.
        $mrkdwn = preg_replace('/(?<=^|[\s;,(])~{2}([^~\v]+)~{2}(?=$|[\s.!?;,)])/ui', '~$1~', $mrkdwn);

        // Convert markdown headings into Slack `*bold*`.
        $mrkdwn = preg_replace('/^([ ]*)(#+)[ ]+([^#\v]+?)(?:[ ]+\\2)?(?:[ ]+\{[^{}]*\})?$/uim', '$1*$3*', $mrkdwn);

        // Convert markdown list items into Slack `:li:`.
        $mrkdwn = preg_replace_callback('/^([ ]*)[*\-][ ]+(?!\[)/uim', function ($m) {
            return str_replace(' ', '   ', $m[1]).':li:'; // Via emoji code.
        }, $mrkdwn); // This turns each space into 3 for nested list items.

        // Convert markdown list items into Slack `- :cbc:` or `- :cb:`.
        $mrkdwn = preg_replace_callback('/^([ ]*)[*\-][ ]+\[([x| ])\](?=[ ]+)/uim', function ($m) {
            return str_replace(' ', '   ', $m[1]).($m['2'] === 'x' ? ':cbc:' : ':cb:');
        }, $mrkdwn); // This turns each space into 3 for nested list items.

        // Tokenize  markdown `<>` links because `<>` are escaped below. Note UTF-8 `⟨` and `⟩` in place of `<` and `>`.
        $mrkdwn = preg_replace('/(?<=^|[\s;,(])\<([a-z][a-z0-9+.\-]*\:[^\s<>]+)\>(?=$|[\s.!?;,)])/ui', '⟨$1⟩', $mrkdwn);

        // Escape special HTML chars. Converts `<>&` into plain text; i.e., disallows raw HTML code.
        $mrkdwn = $this->c::escHtmlChars($mrkdwn); // After `<>` links & issue references.

        // Restore  markdown `<>` links. Note UTF-8 `⟨` and `⟩` in place of `<` and `>`.
        $mrkdwn = preg_replace('/(?<=^|[\s;,(])[⟨]([a-z][a-z0-9+.\-]*\:[^\s<>]+)[⟩](?=$|[\s.!?;,)])/ui', '<$1>', $mrkdwn);

        // Replace images (not Slack compatible) with clickable links.
        $mrkdwn = preg_replace_callback('/\!?\[(?:[^[\]]*|(?R))\]\([a-z][a-z0-9+.\-]*\:[^\s()]+\)(?:[ ]+\{[^{}]*\})?/ui', function ($m) {
            if (mb_stripos($m[0], '![') === false) {
                return $m[0]; // Not an image.
            } else {
                return preg_replace_callback('/\!\[(?<alt_text>[^[\]]*)\]\((?<url>[a-z][a-z0-9+.\-]*\:[^\s()]+)\)/ui', function ($m) {
                    return '<'.$m['url'].'|'.$this->c::escHtmlChars($m['alt_text'] ? $m['alt_text'].' '.__('(image)') : $this->c::midClip(basename($m['url']), 15)).'>';
                }, $m[0]); // Strip away images.
            }
        }, $mrkdwn); // Strip away images.

        // Convert links for Slack compatibility.
        $mrkdwn = preg_replace_callback('/(?<=^|[\s;,(])\[(?<text>[^|[\]]*)\]\((?<url>[a-z][a-z0-9+.\-]*\:[^|\s()]+)\)(?=$|[\s.!?;,)])/ui', function ($m) {
            if (isset($m['text'][0])) {
                return '<'.$m['url'].'|'.$this->c::escHtmlChars($m['text']).'>';
            } else {
                return '<'.$m['url'].'>';
            }
        }, $mrkdwn); // `<url|text>`

        // No more than two consecutive breaks.
        $mrkdwn = $this->c::mbTrim($this->c::normalizeEols($mrkdwn, true));

        return $mrkdwn = &$Tokenizer->restoreGetString();
    }
Slack mrkdwn.

@since 170124.74961 Initial release.

@param mixed $value Input value.
@param array $args  Additional args.

@return string|array|object Mrkdwn'd.