Path: blob/master/src/infrastructure/markup/view/PHUIRemarkupView.php
12241 views
<?php12/**3* Simple API for rendering blocks of Remarkup.4*5* Example usage:6*7* $fancy_text = new PHUIRemarkupView($viewer, $raw_remarkup);8* $view->appendChild($fancy_text);9*10*/11final class PHUIRemarkupView extends AphrontView {1213private $corpus;14private $contextObject;15private $options;16private $oneoff;17private $generateTableOfContents;1819// TODO: In the long run, rules themselves should define available options.20// For now, just define constants here so we can more easily replace things21// later once this is cleaned up.22const OPTION_PRESERVE_LINEBREAKS = 'preserve-linebreaks';23const OPTION_GENERATE_TOC = 'header.generate-toc';2425public function __construct(PhabricatorUser $viewer, $corpus) {26$this->setUser($viewer);27$this->corpus = $corpus;28}2930public function setContextObject($context_object) {31$this->contextObject = $context_object;32return $this;33}3435public function getContextObject() {36return $this->contextObject;37}3839public function setRemarkupOption($key, $value) {40$this->options[$key] = $value;41return $this;42}4344public function setRemarkupOptions(array $options) {45foreach ($options as $key => $value) {46$this->setRemarkupOption($key, $value);47}48return $this;49}5051public function setGenerateTableOfContents($generate) {52$this->generateTableOfContents = $generate;53return $this;54}5556public function getGenerateTableOfContents() {57return $this->generateTableOfContents;58}5960public function getTableOfContents() {61return $this->oneoff->getTableOfContents();62}6364public function render() {65$viewer = $this->getViewer();66$corpus = $this->corpus;67$context = $this->getContextObject();6869$options = $this->options;7071$oneoff = id(new PhabricatorMarkupOneOff())72->setContent($corpus)73->setContentCacheFragment($this->getContentCacheFragment());7475if ($options) {76$oneoff->setEngine($this->getEngine());77} else {78$oneoff->setPreserveLinebreaks(true);79}8081$generate_toc = $this->getGenerateTableOfContents();82$oneoff->setGenerateTableOfContents($generate_toc);83$this->oneoff = $oneoff;8485$content = PhabricatorMarkupEngine::renderOneObject(86$oneoff,87'default',88$viewer,89$context);9091return $content;92}9394private function getEngine() {95$options = $this->options;96$viewer = $this->getViewer();9798$viewer_key = $viewer->getCacheFragment();99$engine_key = $this->getEngineCacheFragment();100101$cache = PhabricatorCaches::getRequestCache();102$cache_key = "remarkup.engine({$viewer_key}, {$engine_key})";103104$engine = $cache->getKey($cache_key);105if (!$engine) {106$engine = PhabricatorMarkupEngine::newMarkupEngine($options);107$cache->setKey($cache_key, $engine);108}109110return $engine;111}112113private function getEngineCacheFragment() {114$options = $this->options;115116ksort($options);117118$engine_key = serialize($options);119$engine_key = PhabricatorHash::digestForIndex($engine_key);120121return $engine_key;122}123124private function getContentCacheFragment() {125$corpus = $this->corpus;126127$content_fragment = PhabricatorHash::digestForIndex($corpus);128$options_fragment = array(129'toc' => $this->getGenerateTableOfContents(),130);131$options_fragment = serialize($options_fragment);132$options_fragment = PhabricatorHash::digestForIndex($options_fragment);133134return "remarkup({$content_fragment}, {$options_fragment})";135}136137}138139140