diff --git a/src/applications/search/engine/PhabricatorSearchEngineAPIMethod.php b/src/applications/search/engine/PhabricatorSearchEngineAPIMethod.php --- a/src/applications/search/engine/PhabricatorSearchEngineAPIMethod.php +++ b/src/applications/search/engine/PhabricatorSearchEngineAPIMethod.php @@ -598,6 +598,11 @@ $view = new PHUIRemarkupView($viewer, $remarkup); + $view->setRemarkupOptions( + array( + PHUIRemarkupView::OPTION_PRESERVE_LINEBREAKS => false, + )); + return id(new PHUIBoxView()) ->appendChild($view) ->addPadding(PHUI::PADDING_LARGE); diff --git a/src/applications/transactions/view/PhabricatorApplicationEditHTTPParameterHelpView.php b/src/applications/transactions/view/PhabricatorApplicationEditHTTPParameterHelpView.php --- a/src/applications/transactions/view/PhabricatorApplicationEditHTTPParameterHelpView.php +++ b/src/applications/transactions/view/PhabricatorApplicationEditHTTPParameterHelpView.php @@ -313,7 +313,14 @@ protected function renderInstructions($corpus) { $viewer = $this->getUser(); - return new PHUIRemarkupView($viewer, $corpus); + $view = new PHUIRemarkupView($viewer, $corpus); + + $view->setRemarkupOptions( + array( + PHUIRemarkupView::OPTION_PRESERVE_LINEBREAKS => false, + )); + + return $view; } } diff --git a/src/infrastructure/markup/PhabricatorMarkupEngine.php b/src/infrastructure/markup/PhabricatorMarkupEngine.php --- a/src/infrastructure/markup/PhabricatorMarkupEngine.php +++ b/src/infrastructure/markup/PhabricatorMarkupEngine.php @@ -470,6 +470,7 @@ $engine = new PhutilRemarkupEngine(); $engine->setConfig('preserve-linebreaks', $options['preserve-linebreaks']); + $engine->setConfig('pygments.enabled', $options['pygments']); $engine->setConfig( 'uri.allowed-protocols', diff --git a/src/infrastructure/markup/PhabricatorMarkupOneOff.php b/src/infrastructure/markup/PhabricatorMarkupOneOff.php --- a/src/infrastructure/markup/PhabricatorMarkupOneOff.php +++ b/src/infrastructure/markup/PhabricatorMarkupOneOff.php @@ -10,6 +10,7 @@ private $content; private $preserveLinebreaks; private $engineRuleset; + private $engine; private $disableCache; public function setEngineRuleset($engine_ruleset) { @@ -35,6 +36,15 @@ return $this->content; } + public function setEngine(PhutilMarkupEngine $engine) { + $this->engine = $engine; + return $this; + } + + public function getEngine() { + return $this->engine; + } + public function setDisableCache($disable_cache) { $this->disableCache = $disable_cache; return $this; @@ -49,6 +59,10 @@ } public function newMarkupEngine($field) { + if ($this->engine) { + return $this->engine; + } + if ($this->engineRuleset) { return PhabricatorMarkupEngine::getEngine($this->engineRuleset); } else if ($this->preserveLinebreaks) { diff --git a/src/infrastructure/markup/view/PHUIRemarkupView.php b/src/infrastructure/markup/view/PHUIRemarkupView.php --- a/src/infrastructure/markup/view/PHUIRemarkupView.php +++ b/src/infrastructure/markup/view/PHUIRemarkupView.php @@ -12,21 +12,19 @@ final class PHUIRemarkupView extends AphrontView { private $corpus; - private $markupType; private $contextObject; + private $options; - const DOCUMENT = 'document'; + // TODO: In the long run, rules themselves should define available options. + // For now, just define constants here so we can more easily replace things + // later once this is cleaned up. + const OPTION_PRESERVE_LINEBREAKS = 'preserve-linebreaks'; public function __construct(PhabricatorUser $viewer, $corpus) { $this->setUser($viewer); $this->corpus = $corpus; } - private function setMarkupType($type) { - $this->markupType($type); - return $this; - } - public function setContextObject($context_object) { $this->contextObject = $context_object; return $this; @@ -36,29 +34,63 @@ return $this->contextObject; } + public function setRemarkupOption($key, $value) { + $this->options[$key] = $value; + return $this; + } + + public function setRemarkupOptions(array $options) { + foreach ($options as $key => $value) { + $this->setRemarkupOption($key, $value); + } + return $this; + } + public function render() { - $viewer = $this->getUser(); + $viewer = $this->getViewer(); $corpus = $this->corpus; $context = $this->getContextObject(); + $options = $this->options; + + $oneoff = id(new PhabricatorMarkupOneOff()) + ->setContent($corpus); + + if ($options) { + $oneoff->setEngine($this->getEngine()); + } else { + $oneoff->setPreserveLinebreaks(true); + } + $content = PhabricatorMarkupEngine::renderOneObject( - id(new PhabricatorMarkupOneOff()) - ->setPreserveLinebreaks(true) - ->setContent($corpus), + $oneoff, 'default', $viewer, $context); - if ($this->markupType == self::DOCUMENT) { - return phutil_tag( - 'div', - array( - 'class' => 'phabricator-remarkup phui-document-view', - ), - $content); + return $content; + } + + private function getEngine() { + $options = $this->options; + $viewer = $this->getViewer(); + + $viewer_key = $viewer->getCacheFragment(); + + ksort($options); + $engine_key = serialize($options); + $engine_key = PhabricatorHash::digestForIndex($engine_key); + + $cache = PhabricatorCaches::getRequestCache(); + $cache_key = "remarkup.engine({$viewer}, {$engine_key})"; + + $engine = $cache->getKey($cache_key); + if (!$engine) { + $engine = PhabricatorMarkupEngine::newMarkupEngine($options); + $cache->setKey($cache_key, $engine); } - return $content; + return $engine; } } diff --git a/src/view/form/AphrontFormView.php b/src/view/form/AphrontFormView.php --- a/src/view/form/AphrontFormView.php +++ b/src/view/form/AphrontFormView.php @@ -84,9 +84,20 @@ } public function appendRemarkupInstructions($remarkup) { - return $this->appendInstructions( - new PHUIRemarkupView($this->getViewer(), $remarkup)); + $view = $this->newInstructionsRemarkupView($remarkup); + return $this->appendInstructions($view); + } + + public function newInstructionsRemarkupView($remarkup) { + $viewer = $this->getViewer(); + $view = new PHUIRemarkupView($viewer, $remarkup); + + $view->setRemarkupOptions( + array( + PHUIRemarkupView::OPTION_PRESERVE_LINEBREAKS => false, + )); + return $view; } public function buildLayoutView() { diff --git a/src/view/form/PHUIFormLayoutView.php b/src/view/form/PHUIFormLayoutView.php --- a/src/view/form/PHUIFormLayoutView.php +++ b/src/view/form/PHUIFormLayoutView.php @@ -31,14 +31,11 @@ } public function appendRemarkupInstructions($remarkup) { - if ($this->getUser() === null) { - throw new PhutilInvalidStateException('setUser'); - } - - $viewer = $this->getUser(); - $instructions = new PHUIRemarkupView($viewer, $remarkup); + $view = id(new AphrontFormView()) + ->setViewer($this->getViewer()) + ->newInstructionsRemarkupView($remarkup); - return $this->appendInstructions($instructions); + return $this->appendInstructions($view); } public function render() {