@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add an "eval" rule to Remarkup

Summary:
Ref T13658. This adds a simple expression evaluator to Remarkup and supports platform name expressions. The syntax is:

```
${{{strings.platform.server.name}}}
```

Note that this won't work inside code blocks (or literal blocks, or other block-level literal elements) right now, although it could be made to selectively (the ".path" expressions might be useful in documentation codeblocks).

Test Plan: {F9391006}

Reviewers: cspeckmim

Reviewed By: cspeckmim

Maniphest Tasks: T13658

Differential Revision: https://secure.phabricator.com/D21713

+104 -1
+2
src/__phutil_library_map__.php
··· 5770 5770 'PhutilRemarkupEngine' => 'infrastructure/markup/remarkup/PhutilRemarkupEngine.php', 5771 5771 'PhutilRemarkupEngineTestCase' => 'infrastructure/markup/remarkup/__tests__/PhutilRemarkupEngineTestCase.php', 5772 5772 'PhutilRemarkupEscapeRemarkupRule' => 'infrastructure/markup/markuprule/PhutilRemarkupEscapeRemarkupRule.php', 5773 + 'PhutilRemarkupEvalRule' => 'infrastructure/markup/markuprule/PhutilRemarkupEvalRule.php', 5773 5774 'PhutilRemarkupHeaderBlockRule' => 'infrastructure/markup/blockrule/PhutilRemarkupHeaderBlockRule.php', 5774 5775 'PhutilRemarkupHighlightRule' => 'infrastructure/markup/markuprule/PhutilRemarkupHighlightRule.php', 5775 5776 'PhutilRemarkupHorizontalRuleBlockRule' => 'infrastructure/markup/blockrule/PhutilRemarkupHorizontalRuleBlockRule.php', ··· 12770 12771 'PhutilRemarkupEngine' => 'PhutilMarkupEngine', 12771 12772 'PhutilRemarkupEngineTestCase' => 'PhutilTestCase', 12772 12773 'PhutilRemarkupEscapeRemarkupRule' => 'PhutilRemarkupRule', 12774 + 'PhutilRemarkupEvalRule' => 'PhutilRemarkupRule', 12773 12775 'PhutilRemarkupHeaderBlockRule' => 'PhutilRemarkupBlockRule', 12774 12776 'PhutilRemarkupHighlightRule' => 'PhutilRemarkupRule', 12775 12777 'PhutilRemarkupHorizontalRuleBlockRule' => 'PhutilRemarkupBlockRule',
+2 -1
src/infrastructure/markup/PhabricatorMarkupEngine.php
··· 42 42 private $objects = array(); 43 43 private $viewer; 44 44 private $contextObject; 45 - private $version = 20; 45 + private $version = 21; 46 46 private $engineCaches = array(); 47 47 private $auxiliaryConfig = array(); 48 48 ··· 504 504 505 505 $rules = array(); 506 506 $rules[] = new PhutilRemarkupEscapeRemarkupRule(); 507 + $rules[] = new PhutilRemarkupEvalRule(); 507 508 $rules[] = new PhutilRemarkupMonospaceRule(); 508 509 509 510
+100
src/infrastructure/markup/markuprule/PhutilRemarkupEvalRule.php
··· 1 + <?php 2 + 3 + final class PhutilRemarkupEvalRule extends PhutilRemarkupRule { 4 + 5 + const KEY_EVAL = 'eval'; 6 + 7 + public function getPriority() { 8 + return 50; 9 + } 10 + 11 + public function apply($text) { 12 + return preg_replace_callback( 13 + '/\${{{(.+?)}}}/', 14 + array($this, 'newExpressionToken'), 15 + $text); 16 + } 17 + 18 + public function newExpressionToken(array $matches) { 19 + $expression = $matches[1]; 20 + 21 + if (!$this->isFlatText($expression)) { 22 + return $matches[0]; 23 + } 24 + 25 + $engine = $this->getEngine(); 26 + $token = $engine->storeText($expression); 27 + 28 + $list_key = self::KEY_EVAL; 29 + $expression_list = $engine->getTextMetadata($list_key, array()); 30 + 31 + $expression_list[] = array( 32 + 'token' => $token, 33 + 'expression' => $expression, 34 + 'original' => $matches[0], 35 + ); 36 + 37 + $engine->setTextMetadata($list_key, $expression_list); 38 + 39 + return $token; 40 + } 41 + 42 + public function didMarkupText() { 43 + $engine = $this->getEngine(); 44 + 45 + $list_key = self::KEY_EVAL; 46 + $expression_list = $engine->getTextMetadata($list_key, array()); 47 + 48 + foreach ($expression_list as $expression_item) { 49 + $token = $expression_item['token']; 50 + $expression = $expression_item['expression']; 51 + 52 + $result = $this->evaluateExpression($expression); 53 + 54 + if ($result === null) { 55 + $result = $expression_item['original']; 56 + } 57 + 58 + $engine->overwriteStoredText($token, $result); 59 + } 60 + } 61 + 62 + private function evaluateExpression($expression) { 63 + static $string_map; 64 + 65 + if ($string_map === null) { 66 + $string_map = array( 67 + 'strings' => array( 68 + 'platform' => array( 69 + 'server' => array( 70 + 'name' => pht('Phabricator'), 71 + 'path' => pht('phabricator/'), 72 + ), 73 + 'client' => array( 74 + 'name' => pht('Arcanist'), 75 + 'path' => pht('arcanist/'), 76 + ), 77 + ), 78 + ), 79 + ); 80 + } 81 + 82 + $parts = explode('.', $expression); 83 + 84 + $cursor = $string_map; 85 + foreach ($parts as $part) { 86 + if (isset($cursor[$part])) { 87 + $cursor = $cursor[$part]; 88 + } else { 89 + break; 90 + } 91 + } 92 + 93 + if (is_string($cursor)) { 94 + return $cursor; 95 + } 96 + 97 + return null; 98 + } 99 + 100 + }