Path: blob/master/src/infrastructure/markup/rule/PhabricatorKeyboardRemarkupRule.php
12241 views
<?php12final class PhabricatorKeyboardRemarkupRule extends PhutilRemarkupRule {34public function getPriority() {5return 200.0;6}78public function apply($text) {9return preg_replace_callback(10'@{key\b((?:[^}\\\\]+|\\\\.)*)}@m',11array($this, 'markupKeystrokes'),12$text);13}1415public function markupKeystrokes(array $matches) {16if (!$this->isFlatText($matches[0])) {17return $matches[0];18}1920$keys = explode(' ', $matches[1]);21foreach ($keys as $k => $v) {22$v = trim($v, " \n");23$v = preg_replace('/\\\\(.)/', '\\1', $v);24if (!strlen($v)) {25unset($keys[$k]);26continue;27}28$keys[$k] = $v;29}3031$special = array(32array(33'name' => pht('Command'),34'symbol' => "\xE2\x8C\x98",35'aliases' => array(36'cmd',37'command',38),39),40array(41'name' => pht('Option'),42'symbol' => "\xE2\x8C\xA5",43'aliases' => array(44'opt',45'option',46),47),48array(49'name' => pht('Shift'),50'symbol' => "\xE2\x87\xA7",51'aliases' => array(52'shift',53),54),55array(56'name' => pht('Escape'),57'symbol' => "\xE2\x8E\x8B",58'aliases' => array(59'esc',60'escape',61),62),63array(64'name' => pht('Enter'),65'symbol' => "\xE2\x8F\x8E",66'aliases' => array(67'enter',68'return',69),70),71array(72'name' => pht('Control'),73'symbol' => "\xE2\x8C\x83",74'aliases' => array(75'ctrl',76'control',77),78),79array(80'name' => pht('Up'),81'symbol' => "\xE2\x86\x91",82'heavy' => "\xE2\xAC\x86",83'aliases' => array(84'up',85'arrow-up',86'up-arrow',87'north',88),89),90array(91'name' => pht('Tab'),92'symbol' => "\xE2\x87\xA5",93'aliases' => array(94'tab',95),96),97array(98'name' => pht('Right'),99'symbol' => "\xE2\x86\x92",100'heavy' => "\xE2\x9E\xA1",101'aliases' => array(102'right',103'right-arrow',104'arrow-right',105'east',106),107),108array(109'name' => pht('Left'),110'symbol' => "\xE2\x86\x90",111'heavy' => "\xE2\xAC\x85",112'aliases' => array(113'left',114'left-arrow',115'arrow-left',116'west',117),118),119array(120'name' => pht('Down'),121'symbol' => "\xE2\x86\x93",122'heavy' => "\xE2\xAC\x87",123'aliases' => array(124'down',125'down-arrow',126'arrow-down',127'south',128),129),130array(131'name' => pht('Up Right'),132'symbol' => "\xE2\x86\x97",133'heavy' => "\xE2\xAC\x88",134'aliases' => array(135'up-right',136'upright',137'up-right-arrow',138'upright-arrow',139'arrow-up-right',140'arrow-upright',141'northeast',142'north-east',143),144),145array(146'name' => pht('Down Right'),147'symbol' => "\xE2\x86\x98",148'heavy' => "\xE2\xAC\x8A",149'aliases' => array(150'down-right',151'downright',152'down-right-arrow',153'downright-arrow',154'arrow-down-right',155'arrow-downright',156'southeast',157'south-east',158),159),160array(161'name' => pht('Down Left'),162'symbol' => "\xE2\x86\x99",163'heavy' => "\xE2\xAC\x8B",164'aliases' => array(165'down-left',166'downleft',167'down-left-arrow',168'downleft-arrow',169'arrow-down-left',170'arrow-downleft',171'southwest',172'south-west',173),174),175array(176'name' => pht('Up Left'),177'symbol' => "\xE2\x86\x96",178'heavy' => "\xE2\xAC\x89",179'aliases' => array(180'up-left',181'upleft',182'up-left-arrow',183'upleft-arrow',184'arrow-up-left',185'arrow-upleft',186'northwest',187'north-west',188),189),190);191192$map = array();193foreach ($special as $spec) {194foreach ($spec['aliases'] as $alias) {195$map[$alias] = $spec;196}197}198199$is_text = $this->getEngine()->isTextMode();200$is_html_mail = $this->getEngine()->isHTMLMailMode();201202if ($is_html_mail) {203$key_style = array(204'display: inline-block;',205'min-width: 1em;',206'padding: 4px 5px 5px;',207'font-weight: normal;',208'font-size: 0.8rem;',209'text-align: center;',210'text-decoration: none;',211'line-height: 0.6rem;',212'border-radius: 3px;',213'box-shadow: inset 0 -1px 0 rgba(71, 87, 120, 0.08);',214'user-select: none;',215'background: #f7f7f7;',216'border: 1px solid #C7CCD9;',217);218$key_style = implode(' ', $key_style);219220$join_style = array(221'padding: 0 4px;',222'color: #92969D;',223);224$join_style = implode(' ', $join_style);225} else {226$key_style = null;227$join_style = null;228}229230$parts = array();231foreach ($keys as $k => $v) {232$normal = phutil_utf8_strtolower($v);233if (isset($map[$normal])) {234$spec = $map[$normal];235} else {236$spec = array(237'name' => null,238'symbol' => $v,239);240}241242if ($is_text) {243$parts[] = '['.$spec['symbol'].']';244} else {245$parts[] = phutil_tag(246'kbd',247array(248'title' => $spec['name'],249'style' => $key_style,250),251$spec['symbol']);252}253}254255if ($is_text) {256$parts = implode(' + ', $parts);257} else {258$glue = phutil_tag(259'span',260array(261'class' => 'kbd-join',262'style' => $join_style,263),264'+');265$parts = phutil_implode_html($glue, $parts);266}267268return $this->getEngine()->storeText($parts);269}270271}272273274