diff --git a/src/markup/engine/__tests__/remarkup/block-then-list.txt b/src/markup/engine/__tests__/remarkup/block-then-list.txt index 01cdb81..c18ebfd 100644 --- a/src/markup/engine/__tests__/remarkup/block-then-list.txt +++ b/src/markup/engine/__tests__/remarkup/block-then-list.txt @@ -1,12 +1,12 @@ lang=txt code block - still a code block ~~~~~~~~~~
code block
 
 - still a code block
~~~~~~~~~~ code block - + - still a code block diff --git a/src/markup/engine/__tests__/remarkup/diff.txt b/src/markup/engine/__tests__/remarkup/diff.txt index 18f3694..602e8b3 100644 --- a/src/markup/engine/__tests__/remarkup/diff.txt +++ b/src/markup/engine/__tests__/remarkup/diff.txt @@ -1,36 +1,36 @@ here is a diff lang=diff @@ derp derp @@ x y - x - y + z derp derp ~~~~~~~~~~

here is a diff

@@ derp derp @@
 x
 y
 
 - x
 - y
 + z

derp derp

~~~~~~~~~~ here is a diff @@ derp derp @@ x y - + - x - y + z derp derp diff --git a/src/markup/engine/__tests__/remarkup/tick-block-multi.txt b/src/markup/engine/__tests__/remarkup/tick-block-multi.txt index 5ff5d76..563db64 100644 --- a/src/markup/engine/__tests__/remarkup/tick-block-multi.txt +++ b/src/markup/engine/__tests__/remarkup/tick-block-multi.txt @@ -1,18 +1,18 @@ ```code more code more code``` ~~~~~~~~~~
code
 
 more code
 
 more code
~~~~~~~~~~ code - + more code - + more code diff --git a/src/markup/engine/__tests__/remarkup/trailing-whitespace-codeblock.txt b/src/markup/engine/__tests__/remarkup/trailing-whitespace-codeblock.txt new file mode 100644 index 0000000..2187cca --- /dev/null +++ b/src/markup/engine/__tests__/remarkup/trailing-whitespace-codeblock.txt @@ -0,0 +1,39 @@ + lang=txt + code block + code block + + + + + code block + + + + + code block +~~~~~~~~~~ +
code block
+code block
+
+
+
+
+code block
+
+
+          
+
+code block
+~~~~~~~~~~ + code block + code block + + + + + code block + + + + + code block diff --git a/src/markup/engine/remarkup/blockrule/PhutilRemarkupEngineRemarkupCodeBlockRule.php b/src/markup/engine/remarkup/blockrule/PhutilRemarkupEngineRemarkupCodeBlockRule.php index f628e3d..928704a 100644 --- a/src/markup/engine/remarkup/blockrule/PhutilRemarkupEngineRemarkupCodeBlockRule.php +++ b/src/markup/engine/remarkup/blockrule/PhutilRemarkupEngineRemarkupCodeBlockRule.php @@ -1,188 +1,187 @@ getBlockPattern(), $block)) { return false; } if (preg_match('@^[a-z]+://\S+$@', trim($block))) { return false; } return true; } public function shouldContinueWithBlock($block, $last_block) { // If the first code block begins with ```, we keep matching blocks until // we hit a terminating ```, regardless of their content. if (preg_match('/^```/', $last_block)) { if (preg_match('/```$/', $last_block)) { return false; } return true; } // If we just matched a code block based on indentation, always match the // next block if it is indented, too. This basically means that we'll treat // lists after code blocks as more code, but usually the "-" is from a diff // or from objective C or something; it is rare to intentionally follow a // code block with a list. if (preg_match('/^\s{2,}/', $block)) { return true; } return false; } public function shouldMergeBlocks() { return true; } public function markupText($text) { if (preg_match('/^```/', $text)) { // If this is a ```-style block, trim off the backticks. $text = preg_replace('/```\s*$/', '', substr($text, 3)); } $lines = explode("\n", $text); $options = array( 'counterexample' => false, 'lang' => null, 'name' => null, 'lines' => null, ); $parser = new PhutilSimpleOptions(); $custom = $parser->parse(head($lines)); if ($custom) { $valid = true; foreach ($custom as $key => $value) { if (!array_key_exists($key, $options)) { $valid = false; break; } } if ($valid) { array_shift($lines); $options = $custom + $options; } } // Normalize the text back to a 0-level indent. $min_indent = 80; foreach ($lines as $line) { for ($ii = 0; $ii < strlen($line); $ii++) { if ($line[$ii] != ' ') { $min_indent = min($ii, $min_indent); break; } } } $text = implode("\n", $lines); if ($min_indent) { $indent_string = str_repeat(' ', $min_indent); $text = preg_replace('/^'.$indent_string.'/m', '', $text); } if ($this->getEngine()->isTextMode()) { $out = array(); $header = array(); if ($options['counterexample']) { $header[] = 'counterexample'; } if ($options['name'] != '') { $header[] = 'name='.$options['name']; } if ($header) { $out[] = implode(', ', $header); } $text = preg_replace('/^/m', ' ', $text); - $text = preg_replace('/^\s+$/m', '', $text); $out[] = $text; return implode("\n", $out); } if (empty($options['lang'])) { // If the user hasn't specified "lang=..." explicitly, try to guess the // language. If we fail, fall back to configured defaults. $lang = PhutilLanguageGuesser::guessLanguage($text); if (!$lang) { $lang = nonempty( $this->getEngine()->getConfig('phutil.codeblock.language-default'), 'php'); } $options['lang'] = $lang; } $code_body = $this->highlightSource($text, $options); $name_header = null; if ($options['name']) { $name_header = phutil_tag( 'div', array( 'class' => 'remarkup-code-header', ), $options['name']); } return phutil_tag( 'div', array( 'class' => 'remarkup-code-block', 'data-code-lang' => $options['lang'], 'data-sigil' => 'remarkup-code-block', ), array($name_header, $code_body)); } private function highlightSource($text, array $options) { if ($options['counterexample']) { $aux_class = ' remarkup-counterexample'; } else { $aux_class = null; } $aux_style = null; if ($options['lines']) { // Put a minimum size on this because the scrollbar is otherwise // unusable. $height = max(6, (int)$options['lines']); $aux_style = 'max-height: '.(2 * $height).'em;'; } $engine = $this->getEngine()->getConfig('syntax-highlighter.engine'); if (!$engine) { $engine = 'PhutilDefaultSyntaxHighlighterEngine'; } $engine = newv($engine, array()); $engine->setConfig( 'pygments.enabled', $this->getEngine()->getConfig('pygments.enabled')); return phutil_tag( 'pre', array( 'class' => 'remarkup-code'.$aux_class, 'style' => $aux_style, ), PhutilSafeHTML::applyFunction( 'trim', $engine->highlightSource($options['lang'], $text))); } }