$1', $text); $text = preg_replace('/^##### (.+?)$/m', '
$1
', $text); $text = preg_replace('/^#### (.+?)$/m', '

$1

', $text); $text = preg_replace('/^### (.+?)$/m', '

$1

', $text); $text = preg_replace('/^## (.+?)$/m', '

$1

', $text); $text = preg_replace('/^# (.+?)$/m', '

$1

', $text); $text = preg_replace('/!\[([^\]]*?)\]\(([^)]+?)\)/', '$1', $text); $text = preg_replace('/\[([^\]]+?)\]\(([^)]+?)\)/', '$1', $text); $text = preg_replace('/(?$1', $text); $text = preg_replace('/(?$1', $text); $text = preg_replace('/(?$1', $text); $text = preg_replace('/(?$1', $text); $text = preg_replace('/(?$1', $text); $text = preg_replace('/(?$1', $text); $text = preg_replace('/~~([^~\n]+?)~~/', '$1', $text); $text = preg_replace('/^\s*---\s*$/m', '
', $text); $text = preg_replace('/^\s*\*\*\*\s*$/m', '
', $text); $text = preg_replace('/^> (.+?)$/m', '
$1
', $text); $text = preg_replace('/^(\s*)[\*\-\+] (.+?)$/m', '$1
  • $2
  • ', $text); $text = preg_replace('/^(\s*)\d+\. (.+?)$/m', '$1
  • $2
  • ', $text); $text = self::wrapLists($text); $text = preg_replace_callback('/(?:^\|.+\|\s*$\n?)+/m', function($matches) { return self::parseTable($matches[0]); }, $text); $text = self::wrapParagraphs($text); foreach ($codeBlocks as $placeholder => $content) { $escapedContent = htmlspecialchars($content, ENT_QUOTES, 'UTF-8'); $codeHtml = '
    ' . $escapedContent . '
    '; $text = str_replace($placeholder, $codeHtml, $text); } foreach ($inlineCodes as $placeholder => $content) { $escapedContent = htmlspecialchars($content, ENT_QUOTES, 'UTF-8'); $codeHtml = '' . $escapedContent . ''; $text = str_replace($placeholder, $codeHtml, $text); } return $text; } private static function wrapLists($text) { $lines = explode("\n", $text); $result = []; $inList = false; $listType = ''; $lastWasListItem = false; foreach ($lines as $line) { if (preg_match('/^(\s*)
  • "; $listType = $newListType; $inList = true; } elseif ($listType !== $newListType) { if (!($listType === 'ol' && $newListType === 'ol')) { $result[] = ""; $result[] = "<$newListType class=\"markdown-list\">"; $listType = $newListType; } } $result[] = $line; $lastWasListItem = true; } else { if ($inList && trim($line) === '' && $lastWasListItem) { $lastWasListItem = false; continue; } if ($inList && trim($line) !== '') { $result[] = ""; $inList = false; } if (trim($line) !== '') { $result[] = $line; $lastWasListItem = false; } } } if ($inList) { $result[] = ""; } return implode("\n", $result); } private static function parseTable($table) { $table = trim($table); $rows = explode("\n", $table); $html = ''; $isHeader = true; foreach ($rows as $row) { if (empty(trim($row))) continue; if (preg_match('/^\|[\s\-\|:]+\|$/', $row)) { $isHeader = false; continue; } $cells = explode('|', trim($row, '|')); $cells = array_map('trim', $cells); $tag = $isHeader ? 'th' : 'td'; $class = $isHeader ? 'markdown-th' : 'markdown-td'; $html .= ''; foreach ($cells as $cell) { $html .= "<$tag class=\"$class\">$cell"; } $html .= ''; if ($isHeader) $isHeader = false; } $html .= '
    '; return $html; } private static function wrapParagraphs($text) { $paragraphs = preg_split('/\n\s*\n/', $text); $result = []; foreach ($paragraphs as $paragraph) { $paragraph = trim($paragraph); if (empty($paragraph)) continue; if (preg_match('/^XCODEBLOCKREPLACEX\d+XCODEBLOCKREPLACEX$/', $paragraph)) { $result[] = $paragraph; } elseif (preg_match('/^<(h[1-6]|ul|ol|blockquote|pre|hr|table|div)/i', $paragraph)) { $result[] = $paragraph; } else { $paragraph = preg_replace('/\n(?!<)/', '
    ', $paragraph); $result[] = '

    ' . $paragraph . '

    '; } } return implode("\n\n", $result); } } ?>