Page MenuHomePhorge

D25299.1732650230.diff
No OneTemporary

D25299.1732650230.diff

diff --git a/src/infrastructure/markup/blockrule/PhutilRemarkupCodeBlockRule.php b/src/infrastructure/markup/blockrule/PhutilRemarkupCodeBlockRule.php
--- a/src/infrastructure/markup/blockrule/PhutilRemarkupCodeBlockRule.php
+++ b/src/infrastructure/markup/blockrule/PhutilRemarkupCodeBlockRule.php
@@ -44,7 +44,18 @@
}
public function markupText($text, $children) {
- if (preg_match('/^\s*```/', $text)) {
+ // Header/footer eventually useful to be nice with "flavored markdown".
+ // When it starts with ```stuff the header is 'stuff' (->language)
+ // When it ends with stuff``` the footer is 'stuff' (->garbage)
+ $header_line = null;
+ $footer_line = null;
+
+ $matches = null;
+ if (preg_match('/^\s*```(.*)/', $text, $matches)) {
+ if (isset($matches[1])) {
+ $header_line = $matches[1];
+ }
+
// If this is a ```-style block, trim off the backticks and any leading
// blank line.
$text = preg_replace('/^\s*```(\s*\n)?/', '', $text);
@@ -52,6 +63,13 @@
}
$lines = explode("\n", $text);
+
+ // If we have a flavored header, it has sense to look for the footer.
+ if ($header_line !== null && $lines) {
+ $footer_line = $lines[last_key($lines)];
+ }
+
+ // Strip final empty lines
while ($lines && !strlen(last($lines))) {
unset($lines[last_key($lines)]);
}
@@ -65,20 +83,35 @@
$parser = new PhutilSimpleOptions();
$custom = $parser->parse(head($lines));
+ $valid_options = null;
if ($custom) {
- $valid = true;
+ $valid_options = true;
foreach ($custom as $key => $value) {
if (!array_key_exists($key, $options)) {
- $valid = false;
+ $valid_options = false;
break;
}
}
- if ($valid) {
+ if ($valid_options) {
array_shift($lines);
$options = $custom + $options;
}
}
+ // Check for flavored markdown only if there was no "lang=" or other options.
+ // We are strict to don't conflict with legitimate content in Remarkup.
+ if (
+ $valid_options === false &&
+ $header_line !== null &&
+ $footer_line === '' &&
+ count($lines) > 1
+ ) {
+ if ($this->isKnownLanguageCode($header_line)) {
+ array_shift($lines);
+ $options['lang'] = $header_line;
+ }
+ }
+
// Normalize the text back to a 0-level indent.
$min_indent = 80;
foreach ($lines as $line) {
@@ -249,4 +282,59 @@
$engine->highlightSource($options['lang'], $text)));
}
+ /**
+ * Check if a language code can be used in flavored markdown.
+ * @param string $lang Language code after backticks
+ * @return bool
+ */
+ private function isKnownLanguageCode($lang) {
+ return in_array($lang, $this->getKnownLanguageCodes(), true);
+ }
+
+ /**
+ * Get all the available languages for flavored markdown.
+ * @return array
+ */
+ private function getKnownLanguageCodes() {
+ // This is a friendly subset from https://pygments.org/languages/
+ return [
+ 'arduino',
+ 'assembly',
+ 'awk',
+ 'bash',
+ 'bat',
+ 'c',
+ 'cmake',
+ 'cobol',
+ 'cpp',
+ 'css',
+ 'csharp',
+ 'dart',
+ 'delphi',
+ 'fortran',
+ 'go',
+ 'groovy',
+ 'haskell',
+ 'java',
+ 'javascript',
+ 'kotlin',
+ 'lisp',
+ 'lua',
+ 'matlab',
+ 'make',
+ 'perl',
+ 'php',
+ 'powershell',
+ 'python',
+ 'r',
+ 'ruby',
+ 'rust',
+ 'scala',
+ 'sh',
+ 'sql',
+ 'typescript',
+ 'vba',
+ ];
+ }
+
}
diff --git a/src/infrastructure/markup/remarkup/__tests__/PhutilRemarkupEngineTestCase.php b/src/infrastructure/markup/remarkup/__tests__/PhutilRemarkupEngineTestCase.php
--- a/src/infrastructure/markup/remarkup/__tests__/PhutilRemarkupEngineTestCase.php
+++ b/src/infrastructure/markup/remarkup/__tests__/PhutilRemarkupEngineTestCase.php
@@ -2,6 +2,8 @@
/**
* Test cases for @{class:PhutilRemarkupEngine}.
+ * @TODO: This unit is not always triggered when you need it.
+ * https://we.phorge.it/T15500
*/
final class PhutilRemarkupEngineTestCase extends PhutilTestCase {
diff --git a/src/infrastructure/markup/remarkup/__tests__/remarkup/tick-block-flavored.txt b/src/infrastructure/markup/remarkup/__tests__/remarkup/tick-block-flavored.txt
new file mode 100644
--- /dev/null
+++ b/src/infrastructure/markup/remarkup/__tests__/remarkup/tick-block-flavored.txt
@@ -0,0 +1,7 @@
+```cpp
+code
+```
+~~~~~~~~~~
+<div class="remarkup-code-block" data-code-lang="cpp" data-sigil="remarkup-code-block"><pre class="remarkup-code">code</pre></div>
+~~~~~~~~~~
+ code
diff --git a/src/infrastructure/markup/remarkup/__tests__/remarkup/tick-block-multi-flavored-comment.txt b/src/infrastructure/markup/remarkup/__tests__/remarkup/tick-block-multi-flavored-comment.txt
new file mode 100644
--- /dev/null
+++ b/src/infrastructure/markup/remarkup/__tests__/remarkup/tick-block-multi-flavored-comment.txt
@@ -0,0 +1,18 @@
+```#comment
+code
+
+#more comment
+more code```
+
+~~~~~~~~~~
+<div class="remarkup-code-block" data-code-lang="text" data-sigil="remarkup-code-block"><pre class="remarkup-code">#comment
+code
+
+#more comment
+more code</pre></div>
+~~~~~~~~~~
+ #comment
+ code
+
+ #more comment
+ more code
diff --git a/src/infrastructure/markup/remarkup/__tests__/remarkup/tick-block-multi-flavored-empty.txt b/src/infrastructure/markup/remarkup/__tests__/remarkup/tick-block-multi-flavored-empty.txt
new file mode 100644
--- /dev/null
+++ b/src/infrastructure/markup/remarkup/__tests__/remarkup/tick-block-multi-flavored-empty.txt
@@ -0,0 +1,9 @@
+```
+cpp
+second line```
+~~~~~~~~~~
+<div class="remarkup-code-block" data-code-lang="text" data-sigil="remarkup-code-block"><pre class="remarkup-code">cpp
+second line</pre></div>
+~~~~~~~~~~
+ cpp
+ second line
diff --git a/src/infrastructure/markup/remarkup/__tests__/remarkup/tick-block-multi-flavored.txt b/src/infrastructure/markup/remarkup/__tests__/remarkup/tick-block-multi-flavored.txt
new file mode 100644
--- /dev/null
+++ b/src/infrastructure/markup/remarkup/__tests__/remarkup/tick-block-multi-flavored.txt
@@ -0,0 +1,20 @@
+```cpp
+code
+
+more code
+
+more code
+```
+
+~~~~~~~~~~
+<div class="remarkup-code-block" data-code-lang="cpp" data-sigil="remarkup-code-block"><pre class="remarkup-code">code
+
+more code
+
+more code</pre></div>
+~~~~~~~~~~
+ code
+
+ more code
+
+ more code

File Metadata

Mime Type
text/plain
Expires
Tue, Nov 26, 19:43 (18 h, 45 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
997854
Default Alt Text
D25299.1732650230.diff (6 KB)

Event Timeline