[ Index ] |
PHP Cross Reference of Phabricator |
[Summary view] [Print] [Text view]
1 <?php 2 3 final class DivinerSymbolRemarkupRule extends PhutilRemarkupRule { 4 5 const KEY_RULE_ATOM_REF = 'rule.diviner.atomref'; 6 7 public function getPriority() { 8 return 200.0; 9 } 10 11 public function apply($text) { 12 // Grammar here is: 13 // 14 // rule = '@{' maybe_type name maybe_title '}' 15 // maybe_type = null | type ':' | type '@' book ':' 16 // name = name | name '@' context 17 // maybe_title = null | '|' title 18 // 19 // So these are all valid: 20 // 21 // @{name} 22 // @{type : name} 23 // @{name | title} 24 // @{type @ book : name @ context | title} 25 26 return preg_replace_callback( 27 '/(?:^|\B)@{'. 28 '(?:(?P<type>[^:]+?):)?'. 29 '(?P<name>[^}|]+?)'. 30 '(?:[|](?P<title>[^}]+))?'. 31 '}/', 32 array($this, 'markupSymbol'), 33 $text); 34 } 35 36 public function markupSymbol($matches) { 37 if (!$this->isFlatText($matches[0])) { 38 return $matches[0]; 39 } 40 41 $type = (string)idx($matches, 'type'); 42 $name = (string)$matches['name']; 43 $title = (string)idx($matches, 'title'); 44 45 // Collapse sequences of whitespace into a single space. 46 $type = preg_replace('/\s+/', ' ', trim($type)); 47 $name = preg_replace('/\s+/', ' ', trim($name)); 48 $title = preg_replace('/\s+/', ' ', trim($title)); 49 50 $ref = array(); 51 52 if (strpos($type, '@') !== false) { 53 list($type, $book) = explode('@', $type, 2); 54 $ref['type'] = trim($type); 55 $ref['book'] = trim($book); 56 } else { 57 $ref['type'] = $type; 58 } 59 60 if (strpos($name, '@') !== false) { 61 list($name, $context) = explode('@', $name, 2); 62 $ref['name'] = trim($name); 63 $ref['context'] = trim($context); 64 } else { 65 $ref['name'] = $name; 66 } 67 68 $ref['title'] = nonempty($title, $name); 69 70 foreach ($ref as $key => $value) { 71 if ($value === '') { 72 unset($ref[$key]); 73 } 74 } 75 76 $engine = $this->getEngine(); 77 $token = $engine->storeText(''); 78 79 $key = self::KEY_RULE_ATOM_REF; 80 $data = $engine->getTextMetadata($key, array()); 81 $data[$token] = $ref; 82 $engine->setTextMetadata($key, $data); 83 84 return $token; 85 } 86 87 public function didMarkupText() { 88 $engine = $this->getEngine(); 89 90 $key = self::KEY_RULE_ATOM_REF; 91 $data = $engine->getTextMetadata($key, array()); 92 93 $renderer = $engine->getConfig('diviner.renderer'); 94 95 foreach ($data as $token => $ref_dict) { 96 $ref = DivinerAtomRef::newFromDictionary($ref_dict); 97 $title = $ref->getTitle(); 98 99 $href = null; 100 if ($renderer) { 101 // Here, we're generating documentation. If possible, we want to find 102 // the real atom ref so we can render the correct default title and 103 // render invalid links in an alternate style. 104 105 $ref = $renderer->normalizeAtomRef($ref); 106 if ($ref) { 107 $title = nonempty($ref->getTitle(), $ref->getName()); 108 $href = $renderer->getHrefForAtomRef($ref); 109 } 110 } else { 111 // Here, we're generating comment text or something like that. Just 112 // link to Diviner and let it sort things out. 113 114 $href = id(new PhutilURI('/diviner/find/')) 115 ->setQueryParams( 116 array( 117 'book' => $ref->getBook(), 118 'name' => $ref->getName(), 119 'type' => $ref->getType(), 120 'context' => $ref->getContext(), 121 'jump' => true, 122 )); 123 } 124 125 // TODO: This probably is not the best place to do this. Move it somewhere 126 // better when it becomes more clear where it should actually go. 127 if ($ref) { 128 switch ($ref->getType()) { 129 case 'function': 130 case 'method': 131 $title = $title.'()'; 132 break; 133 } 134 } 135 136 if ($this->getEngine()->isTextMode()) { 137 if ($href) { 138 $link = $title.' <'.PhabricatorEnv::getProductionURI($href).'>'; 139 } else { 140 $link = $title; 141 } 142 } else if ($href) { 143 if ($this->getEngine()->isHTMLMailMode()) { 144 $href = PhabricatorEnv::getProductionURI($href); 145 } 146 147 $link = $this->newTag( 148 'a', 149 array( 150 'class' => 'atom-ref', 151 'href' => $href, 152 ), 153 $title); 154 } else { 155 $link = $this->newTag( 156 'span', 157 array( 158 'class' => 'atom-ref-invalid', 159 ), 160 $title); 161 } 162 163 $engine->overwriteStoredText($token, $link); 164 } 165 } 166 167 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sun Nov 30 09:20:46 2014 | Cross-referenced by PHPXref 0.7.1 |