Path: blob/master/src/infrastructure/markup/syntax/highlighter/PhutilDivinerSyntaxHighlighter.php
12242 views
<?php12/**3* Simple syntax highlighter for the ".diviner" format, which is just Remarkup4* with a specific ruleset. This should also work alright for Remarkup.5*/6final class PhutilDivinerSyntaxHighlighter extends Phobject {78private $config = array();9private $replaceClass;1011public function setConfig($key, $value) {12$this->config[$key] = $value;13return $this;14}1516public function getHighlightFuture($source) {17$source = phutil_escape_html($source);1819// This highlighter isn't perfect but tries to do an okay job at getting20// some of the basics at least. There's lots of room for improvement.2122$blocks = explode("\n\n", $source);23foreach ($blocks as $key => $block) {24if (preg_match('/^[^ ](?! )/m', $block)) {25$blocks[$key] = $this->highlightBlock($block);26}27}28$source = implode("\n\n", $blocks);2930$source = phutil_safe_html($source);31return new ImmediateFuture($source);32}3334private function highlightBlock($source) {35// Highlight "@{class:...}" links to other documentation pages.36$source = $this->highlightPattern('/@{([\w@]+?):([^}]+?)}/', $source, 'nc');3738// Highlight "@title", "@group", etc.39$source = $this->highlightPattern('/^@(\w+)/m', $source, 'k');4041// Highlight bold, italic and monospace.42$source = $this->highlightPattern('@\\*\\*(.+?)\\*\\*@s', $source, 's');43$source = $this->highlightPattern('@(?<!:)//(.+?)//@s', $source, 's');44$source = $this->highlightPattern(45'@##([\s\S]+?)##|\B`(.+?)`\B@',46$source,47's');4849// Highlight stuff that looks like headers.50$source = $this->highlightPattern('/^=(.*)$/m', $source, 'nv');5152return $source;53}5455private function highlightPattern($regexp, $source, $class) {56$this->replaceClass = $class;57$source = preg_replace_callback(58$regexp,59array($this, 'replacePattern'),60$source);6162return $source;63}6465public function replacePattern($matches) {6667// NOTE: The goal here is to make sure a <span> never crosses a newline.6869$content = $matches[0];70$content = explode("\n", $content);71foreach ($content as $key => $line) {72$content[$key] =73'<span class="'.$this->replaceClass.'">'.74$line.75'</span>';76}77return implode("\n", $content);78}7980}818283