From c6d76daf8c85756f9a9bb2b61bd715f895b2ba35 Mon Sep 17 00:00:00 2001 From: LX <1063823095@qq.com> Date: Fri, 1 Sep 2023 23:35:16 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dmarkdown=E6=A0=BC=E5=BC=8F?= =?UTF-8?q?=E7=9A=84=E6=96=87=E7=AB=A0=E4=B8=AD=E7=9A=84=E9=93=BE=E6=8E=A5?= =?UTF-8?q?=E8=AF=86=E5=88=AB=E6=95=88=E6=9E=9C=EF=BC=8C=E6=8F=90=E5=87=BA?= =?UTF-8?q?=E9=83=A8=E5=88=86=E5=85=AC=E5=85=B1=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Plugin.php | 234 ++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 212 insertions(+), 22 deletions(-) diff --git a/Plugin.php b/Plugin.php index d488486..b65d5e4 100644 --- a/Plugin.php +++ b/Plugin.php @@ -196,6 +196,7 @@ public static function replace(string $text, $widget, $lastResult) $text = empty($lastResult) ? $text : $lastResult; $pluginOption = self::options('ShortLinks'); // 插件选项 $target = ($pluginOption->target) ? ' target="_blank" ' : ''; // 新窗口打开 + if ($pluginOption->convert == 1) { if ($widget->fields) { $fields = unserialize($widget->fields); @@ -204,11 +205,24 @@ public static function replace(string $text, $widget, $lastResult) return $text; } } - // 文章内容和评论内容处理 + + // 文章内容和评论内容处理,默认只处理a标签 @preg_match_all('//', $text, $matches); if ($matches) { foreach ($matches[2] as $link) { - $text = str_replace("href=\"$link\"", "href=\"" . self::convertLink($link) . "\"" . $target, $text); + if(self::isExternalLink($link) ) { + $text = str_replace("href=\"$link\"", "href=\"" . self::convertLink($link) . "\"" . $target, $text); + } + + } + } + + // 强力模式 + if ($pluginOption->forceSwitch == 1) + { + // Markdown格式 + if(strpos($text,'class="md_content"') !== false){ + $text = self::convertExternalLinkToInternalLinkInMarkdown($text); } } } @@ -218,9 +232,9 @@ public static function replace(string $text, $widget, $lastResult) /** * 自定义字段处理 * - * @param Widget_Archive $widget - * @param Typecho_Db_Query $select - * @param mixed $lastResult + * @param Widget_Archive $widget + * @param Typecho_Db_Query $select + * @param mixed $lastResult * @return void * @throws \Typecho\Plugin\Exception */ @@ -233,17 +247,19 @@ public static function fieldsConvert($widget, $select, $lastResult) if ($fieldsList) { foreach ($fieldsList as $field) { if (isset($text->fields[$field])) { - // 非强力模式转换 a 标签 - @preg_match_all('//', $widget->fields[$field], $matches); - if ($matches) { - foreach ($matches[2] as $link) { - $widget->fields[$field] = str_replace("href=\"$link\"", "href=\"" . self::convertLink($link) . "\"", $widget->fields[$field]); + if(self::isExternalLink($link)) { + // 非强力模式转换 a 标签 + @preg_match_all('//', $widget->fields[$field], $matches); + if ($matches) { + foreach ($matches[2] as $link) { + + $widget->fields[$field] = str_replace("href=\"$link\"", "href=\"" . self::convertLink($link) . "\"", $widget->fields[$field]); + } + } + // 强力模式匹配所有链接 + if ($pluginOption->forceSwitch == 1) { + $widget->fields[$field] = self::autoLink($widget->fields[$field]); } - } - - // 强力模式匹配所有链接 - if ($pluginOption->forceSwitch == 1) { - $widget->fields[$field] = self::autoLink($widget->fields[$field]); } } } @@ -304,7 +320,7 @@ public static function convertLink($link, bool $check = true) } // 图片不处理 - if (preg_match('/\.(jpg|jepg|png|ico|bmp|gif|tiff)/i', $link)) { + if (self::isImageUrl($link)) { return $link; } } @@ -314,9 +330,9 @@ public static function convertLink($link, bool $check = true) /** * 强力转换 * - * @param Array $value - * @param mixed $widget - * @param mixed $lastResult + * @param Array $value + * @param mixed $widget + * @param mixed $lastResult * @return Array * @throws \Typecho\Plugin\Exception */ @@ -333,13 +349,12 @@ public static function forceConvert(array $value, $widget, $lastResult): array /** * 文本链接转A标签 * - * @param string $content + * @param string $content * @return string * @throws \Typecho\Plugin\Exception */ public static function autoLink($content) { - $url = '~(?:(https?)://([^\s<]+)|(www\.[^\s<]+?\.[^\s<]+))(?target) ? ' target="_blank" ' : ''; // 新窗口打开 return preg_replace_callback($url, function ($matches) use ($target) { @@ -351,6 +366,33 @@ public static function autoLink($content) } return $matches[0]; }, $content); + + // // 如果当前浏览器地址栏中的url是在后台页面,则不进行转换操作 + // if(self::isAdminPage()){ + // return $content; + // } + + // $url = '~(?:(https?)://([^\s<]+)|(www\.[^\s<]+?\.[^\s<]+))(?target) ? ' target="_blank" ' : ''; // 新窗口打开 + + // @preg_match_all($url, $content, $matches); + // if ($matches) { + // foreach ($matches[0] as $link) { + // if (self::isImageUrl($link)) { + // continue; + // } + // if (strpos($link, '://') !== false ) { + // if(self::isExternalLink($link)) { + // $aLink = '' . $link . ''; + // $content = str_replace($link, $aLink, $content); + // } + // } + // } + // } + // // echo json_encode($matches)."\n"; + // return $content; } /** @@ -459,4 +501,152 @@ public static function db() return Typecho_Db::get(); } } -} + + /** + * 检查url是否外链 + * + * @access private + * @param string $url + * @return boolean + */ + private static function isExternalLink(string $url) + { + $parsedUrl = parse_url($url); + + // 检查url是否包含scheme(协议),例如http://或https:// + if(isset($parsedUrl['scheme']) && ($parsedUrl['scheme'] == 'http' || $parsedUrl['scheme'] == 'https')) { + // 获取当前页面的Host( 192.168.174.130:33310 ) + $currentDomain = $_SERVER['HTTP_HOST']; + + // 获取链接的域名( 192.168.174.130 ) + $linkDomain = $parsedUrl['host']; + + // 检查链接的域名是否与当前页面的域名相同 + if(strpos($currentDomain, $linkDomain) === false) { + return true; // 是外链 + } + } + + return false; // 不是外链 + } + + /** + * 检查url是否图片 + * + * @access private + * @param string $url + * @return boolean + */ + private static function isImageUrl(string $url) + { + // 有的图片链接会带后缀,例如oss类图片,后面再改 + $imageReg = '/\.(jpg|jepg|png|ico|bmp|gif|tiff)/i'; + if (preg_match($imageReg, $url)) { + return true; + }else{ + return false; + } + } + + /** + * 是否后台页面 + * + * @access private + * @return boolean + */ + private static function isAdminPage() + { + if(strpos($_SERVER['REQUEST_URI'],__TYPECHO_ADMIN_DIR__)!==false) { + return true; + }else{ + return false; + } + } + + /** + * 转换markdown中的外链 + * + * @access private + * @param string $text + * @return string + */ + private static function convertExternalLinkToInternalLinkInMarkdown(string $text) + { + // 纯url转换,不将url转换为a标签,这种方式最保险(会失去a标签的特性,本身markdown语法规则就不提供新窗口打开特性) + // []() + $urlReg = '~(?:(https?)://([^\s<]+)|(www\.[^\s<]+?\.[^\s<]+))(?(.|[^.])*?)```/'; + + @preg_match_all($regex, $content, $matches); + if($matches){ + foreach ($matches['matchCode'] as $match) { + $results[] = $match; + } + } + return $results; + } + + /** + * 判断url是否在"代码块"中 + * + * @access private + * @param array[string] $codeBlocks + * @param string $url + * @return boolean + */ + private static function isUrlInCodeBlock(array $codeBlocks,string $url) + { + foreach ($codeBlocks as $codeBlock) { + if (strpos($codeBlock, $url) !== false) { + return true; + } + } + return false; + } + + +} \ No newline at end of file