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 @@ -63,8 +63,11 @@ 'lines' => null, ); + // The options after the first backticks. + $first_line = head($lines); + $parser = new PhutilSimpleOptions(); - $custom = $parser->parse(head($lines)); + $custom = $parser->parse($first_line); if ($custom) { $valid = true; foreach ($custom as $key => $value) { @@ -79,6 +82,16 @@ } } + // Very early, eventually parse the language expressed + // in the very first line, just after the first backticks. + // But, in case, let's remove that line. + if (empty($options['lang']) && $first_line) { + if ($this->isProbablyLanguageCode($first_line)) { + $options['lang'] = $first_line; + array_shift($lines); + } + } + // Normalize the text back to a 0-level indent. $min_indent = 80; foreach ($lines as $line) { @@ -249,4 +262,19 @@ $engine->highlightSource($options['lang'], $text))); } + /** + * Check if a string is very probably a language code + * recognized by the Pygments library (or maybe others). + * + * @param string $s + * @return bool + */ + private function isProbablyLanguageCode($s) { + // If not already specified, try to match the language from: ```thelang + // This regex was manually and empirically crafted to try to match + // all the available stuff from Pygments. + // https://pygments.org/languages/ + return preg_match('/^[a-z0-9\-\+\#\/]+$/', $s); + } + }