[aur-dev] [PATCH 0/4] Add support for markdown code blocks and inline code
Only a subset of markdown is support, i.e.: ``` code blocks ``` and `inline code`. Marcel Korpel (4): Convert markdown codeblocks to HTML code blocks Add support for markdown inline code Add horizontal scrollbar to code blocks when necessary Use a normal font size for code blocks web/html/css/aurweb.css | 5 ++++ web/lib/aur.inc.php | 78 ++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 73 insertions(+), 10 deletions(-) -- 2.4.5
Only codeblocks delimited with ```<newline> are supported. Signed-off-by: Marcel Korpel <marcel.korpel@gmail.com> --- web/lib/aur.inc.php | 49 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/web/lib/aur.inc.php b/web/lib/aur.inc.php index 411d5ee..4b1850f 100644 --- a/web/lib/aur.inc.php +++ b/web/lib/aur.inc.php @@ -596,7 +596,8 @@ function comment_by_id($comment_id) { } /** - * Process submitted comments so any links can be followed + * Process submitted comments so any links can be followed and + * parse markdown code blocks (within ```<newline>) * * @param string $comment Raw user submitted package comment * @@ -605,23 +606,51 @@ function comment_by_id($comment_id) { function parse_comment($comment) { $url_pattern = '/(\b(?:https?|ftp):\/\/[\w\/\#~:.?+=&%@!\-;,]+?' . '(?=[.:?\-;,]*(?:[^\w\/\#~:.?+=&%@!\-;,]|$)))/iS'; + $md_codeblock_delimiter = '/(```)\R/'; + $md_codeblock_active = false; - $matches = preg_split($url_pattern, $comment, -1, + $blocks = preg_split($md_codeblock_delimiter, $comment, -1, PREG_SPLIT_DELIM_CAPTURE); $html = ''; - for ($i = 0; $i < count($matches); $i++) { + for ($i = 0; $i < count($blocks); $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])); + // add start/end of code block + 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) { + // do not convert code blocks (white-space and newlines are + // preserved) + $html .= htmlspecialchars($blocks[$i]); + } else { + $matches = preg_split($url_pattern, $blocks[$i], -1, + PREG_SPLIT_DELIM_CAPTURE); + + for ($j = 0; $j < count($matches); $j++) { + if ($j % 2) { + // convert links + $html .= '<a href="' . htmlspecialchars($matches[$j]) . + '">' . htmlspecialchars($matches[$j]) . '</a>'; + } else { + // convert everything else + $html .= nl2br(htmlspecialchars($matches[$j])); + } + } + } } } + // close possible open code block + if ($md_codeblock_active) { + $html .= '</code></pre><p>'; + } + return $html; } -- 2.4.5
Signed-off-by: Marcel Korpel <marcel.korpel@gmail.com> --- web/lib/aur.inc.php | 47 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/web/lib/aur.inc.php b/web/lib/aur.inc.php index 4b1850f..d0c8c98 100644 --- a/web/lib/aur.inc.php +++ b/web/lib/aur.inc.php @@ -597,7 +597,8 @@ function comment_by_id($comment_id) { /** * Process submitted comments so any links can be followed and - * parse markdown code blocks (within ```<newline>) + * parse markdown code blocks (within ```<newline>) and inline + * code (like `this`) * * @param string $comment Raw user submitted package comment * @@ -608,6 +609,8 @@ function parse_comment($comment) { '(?=[.:?\-;,]*(?:[^\w\/\#~:.?+=&%@!\-;,]|$)))/iS'; $md_codeblock_delimiter = '/(```)\R/'; $md_codeblock_active = false; + $md_code_fragment_delimiter = '/(`)/'; + $md_code_fragment_active = false; $blocks = preg_split($md_codeblock_delimiter, $comment, -1, PREG_SPLIT_DELIM_CAPTURE); @@ -629,23 +632,49 @@ function parse_comment($comment) { // preserved) $html .= htmlspecialchars($blocks[$i]); } else { - $matches = preg_split($url_pattern, $blocks[$i], -1, - PREG_SPLIT_DELIM_CAPTURE); + $code_fragments = preg_split($md_code_fragment_delimiter, $blocks[$i], + -1, PREG_SPLIT_DELIM_CAPTURE); - for ($j = 0; $j < count($matches); $j++) { + for ($j = 0; $j < count($code_fragments); $j++) { if ($j % 2) { - // convert links - $html .= '<a href="' . htmlspecialchars($matches[$j]) . - '">' . htmlspecialchars($matches[$j]) . '</a>'; + // add start/end tag of code fragment + if ($md_code_fragment_active) { + $html .= '</code>'; + $md_code_fragment_active = false; + } else { + $html .= '<code>'; + $md_code_fragment_active = true; + } } else { - // convert everything else - $html .= nl2br(htmlspecialchars($matches[$j])); + if ($md_code_fragment_active) { + // do not convert links within code blocks + $html .= nl2br(htmlspecialchars($code_fragments[$j])); + } else { + $matches = preg_split($url_pattern, $code_fragments[$j], + -1, PREG_SPLIT_DELIM_CAPTURE); + + for ($k = 0; $k < count($matches); $k++) { + if ($k % 2) { + // convert links + $html .= '<a href="' . htmlspecialchars($matches[$k]) . + '">' . htmlspecialchars($matches[$k]) . '</a>'; + } else { + // convert everything else + $html .= nl2br(htmlspecialchars($matches[$k])); + } + } + } } } } } } + // close possible open code fragment + if ($md_code_fragment_active) { + $html .= '</code>'; + } + // close possible open code block if ($md_codeblock_active) { $html .= '</code></pre><p>'; -- 2.4.5
On Sat, 11 Jul 2015 at 20:22:00, Marcel Korpel wrote:
Signed-off-by: Marcel Korpel <marcel.korpel@gmail.com> --- web/lib/aur.inc.php | 47 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 9 deletions(-) [...] + // convert links + $html .= '<a href="' . htmlspecialchars($matches[$k]) . + '">' . htmlspecialchars($matches[$k]) . '</a>'; [...]
Wow, nine levels of indentation. I think this parser code can be simplified a lot. What I would do is split the comment at line breaks and iterate over single lines (means we don't need special handling for the "```" at the end of a comment as well). We also should be able to replace links and inline code with simple preg_replace() or preg_replace_callback() invocations, right?
Signed-off-by: Marcel Korpel <marcel.korpel@gmail.com> --- web/html/css/aurweb.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/web/html/css/aurweb.css b/web/html/css/aurweb.css index b33726c..6bd7eb3 100644 --- a/web/html/css/aurweb.css +++ b/web/html/css/aurweb.css @@ -124,6 +124,10 @@ opacity: 1; } +pre { + overflow-x: auto; +} + legend { padding: 1em 0; } -- 2.4.5
Signed-off-by: Marcel Korpel <marcel.korpel@gmail.com> --- web/html/css/aurweb.css | 1 + 1 file changed, 1 insertion(+) diff --git a/web/html/css/aurweb.css b/web/html/css/aurweb.css index 6bd7eb3..691a634 100644 --- a/web/html/css/aurweb.css +++ b/web/html/css/aurweb.css @@ -125,6 +125,7 @@ } pre { + font-size: 100%; overflow-x: auto; } -- 2.4.5
When a comment and with ``` without a newline character, the delimiter is not correctly recognized. Fix by adding a newline character. Signed-off-by: Marcel Korpel <marcel.korpel@gmail.com> --- web/lib/aur.inc.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/web/lib/aur.inc.php b/web/lib/aur.inc.php index d0c8c98..0073cd8 100644 --- a/web/lib/aur.inc.php +++ b/web/lib/aur.inc.php @@ -612,6 +612,12 @@ function parse_comment($comment) { $md_code_fragment_delimiter = '/(`)/'; $md_code_fragment_active = false; + // repair special case where the last instance of ``` doesn't end with + // a newline character + if (substr($comment, -3) == '```') { + $comment .= "\n"; + } + $blocks = preg_split($md_codeblock_delimiter, $comment, -1, PREG_SPLIT_DELIM_CAPTURE); -- 2.4.5
When a comment ends with ``` without a newline character, the delimiter is not correctly recognized. Fix by adding a newline character. Signed-off-by: Marcel Korpel <marcel.korpel@gmail.com> --- Change since v1: * Fix commit message web/lib/aur.inc.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/web/lib/aur.inc.php b/web/lib/aur.inc.php index d0c8c98..0073cd8 100644 --- a/web/lib/aur.inc.php +++ b/web/lib/aur.inc.php @@ -612,6 +612,12 @@ function parse_comment($comment) { $md_code_fragment_delimiter = '/(`)/'; $md_code_fragment_active = false; + // repair special case where the last instance of ``` doesn't end with + // a newline character + if (substr($comment, -3) == '```') { + $comment .= "\n"; + } + $blocks = preg_split($md_codeblock_delimiter, $comment, -1, PREG_SPLIT_DELIM_CAPTURE); -- 2.4.5
participants (2)
-
Lukas Fleischer
-
Marcel Korpel