Only codeblocks delimited with ```<newline> are supported.

Signed-off-by: Marcel Korpel <[email protected]>
---
Changes from v1:
* Convert one line at a time
* Use preg_replace_callback to convert inline code and URLs
* Now URLs within inline code are also converted, unwanted behaviour?
* Introduces a global ($md_inline_code_active), unwanted?

 web/lib/aur.inc.php | 74 +++++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 60 insertions(+), 14 deletions(-)

diff --git a/web/lib/aur.inc.php b/web/lib/aur.inc.php
index 411d5ee..d370788 100644
--- a/web/lib/aur.inc.php
+++ b/web/lib/aur.inc.php
@@ -603,25 +603,71 @@ function comment_by_id($comment_id) {
  * @return string User comment with links printed in HTML
  */
 function parse_comment($comment) {
-       $url_pattern = '/(\b(?:https?|ftp):\/\/[\w\/\#~:.?+=&%@!\-;,]+?' .
-               '(?=[.:?\-;,]*(?:[^\w\/\#~:.?+=&%@!\-;,]|$)))/iS';
-
-       $matches = preg_split($url_pattern, $comment, -1,
-               PREG_SPLIT_DELIM_CAPTURE);
+       $url_pattern = '/\b(?:https?|ftp):\/\/[\w\/\#~:.?+=&%@!\-;,]+?' .
+               '(?=[.:?\-;,]*(?:[^\w\/\#~:.?+=&%@!\-;,]|$))/iS';
+       $md_codeblock_delimiter = '```';
+       $md_codeblock_active = false;
+       $md_inline_code_delimiter = '/`/';
+       $md_inline_code_active = false;
 
        $html = '';
-       for ($i = 0; $i < count($matches); $i++) {
-               if ($i % 2) {
-                       # convert links
-                       $html .= '<a href="' . htmlspecialchars($matches[$i]) .
-                               '">' .  htmlspecialchars($matches[$i]) . '</a>';
-               }
-               else {
-                       # convert everything else
-                       $html .= nl2br(htmlspecialchars($matches[$i]));
+       $lines = preg_split('/\R/', $comment);
+
+       foreach ($lines as $line) {
+               if ($line == $md_codeblock_delimiter) {
+                       if ($md_codeblock_active) {
+                               $html .= '</code></pre><p>';
+                               $md_codeblock_active = false;
+                       } else {
+                               $html .= '</p><pre><code>';
+                               $md_codeblock_active = true;
+                       }
+               } else {
+                       if ($md_codeblock_active) {
+                               $html .= htmlspecialchars($line) . "\n";
+                       } else {
+                               global $md_inline_code_active;
+
+                               $line = htmlspecialchars($line);
+                               $line = preg_replace_callback(
+                                       $md_inline_code_delimiter,
+                                       function ($matches) {
+                                               global $md_inline_code_active;
+
+                                               if ($md_inline_code_active) {
+                                                       $md_inline_code_active 
= false;
+                                                       return '</code>';
+                                               } else {
+                                                       $md_inline_code_active 
= true;
+                                                       return '<code>';
+                                               }
+                                       },
+                                       $line);
+
+                               $line = preg_replace_callback(
+                                       $url_pattern,
+                                       function ($matches) {
+                                               return '<a href="' . 
$matches[0] .
+                                                       '">' . $matches[0] . 
'</a>';
+                                       },
+                                       $line);
+
+                               $html .= $line . "<br />\n";
+                       }
                }
        }
 
+       // close possible open inline code
+       if ($md_inline_code_active) {
+               $html .= '</code>';
+               $md_inline_code_active = false;
+       }
+
+       // close possible open code block
+       if ($md_codeblock_active) {
+               $html .= '</code></pre><p>';
+       }
+
        return $html;
 }
 
-- 
2.4.5

Reply via email to