mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-18 12:52:42 +01:00
Add a {key ..} Remarkup rule for discussing keystrokes
Summary: Ruleset for styles in D16506. Test Plan: {F1803883} Reviewers: chad Reviewed By: chad Differential Revision: https://secure.phabricator.com/D16510
This commit is contained in:
parent
b7e51877c3
commit
5f43abd7ef
6 changed files with 262 additions and 3 deletions
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
return array(
|
||||
'names' => array(
|
||||
'core.pkg.css' => '6791587e',
|
||||
'core.pkg.css' => 'd28c0515',
|
||||
'core.pkg.js' => '1d376fa9',
|
||||
'darkconsole.pkg.js' => 'e7393ebb',
|
||||
'differential.pkg.css' => '3fb7f532',
|
||||
|
@ -105,7 +105,7 @@ return array(
|
|||
'rsrc/css/application/tokens/tokens.css' => '3d0f239e',
|
||||
'rsrc/css/application/uiexample/example.css' => '528b19de',
|
||||
'rsrc/css/core/core.css' => 'd0801452',
|
||||
'rsrc/css/core/remarkup.css' => '9905d6c4',
|
||||
'rsrc/css/core/remarkup.css' => 'cd912f2c',
|
||||
'rsrc/css/core/syntax.css' => '769d3498',
|
||||
'rsrc/css/core/z-index.css' => '2b01a823',
|
||||
'rsrc/css/diviner/diviner-shared.css' => 'aa3656aa',
|
||||
|
@ -792,7 +792,7 @@ return array(
|
|||
'phabricator-object-selector-css' => '85ee8ce6',
|
||||
'phabricator-phtize' => 'd254d646',
|
||||
'phabricator-prefab' => 'cfd23f37',
|
||||
'phabricator-remarkup-css' => '9905d6c4',
|
||||
'phabricator-remarkup-css' => 'cd912f2c',
|
||||
'phabricator-search-results-css' => '7dea472c',
|
||||
'phabricator-shaped-request' => '7cbe244b',
|
||||
'phabricator-slowvote-css' => 'a94b7230',
|
||||
|
|
|
@ -2707,6 +2707,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorJiraIssueHasObjectEdgeType' => 'applications/doorkeeper/edge/PhabricatorJiraIssueHasObjectEdgeType.php',
|
||||
'PhabricatorJumpNavHandler' => 'applications/search/engine/PhabricatorJumpNavHandler.php',
|
||||
'PhabricatorKeyValueDatabaseCache' => 'applications/cache/PhabricatorKeyValueDatabaseCache.php',
|
||||
'PhabricatorKeyboardRemarkupRule' => 'infrastructure/markup/rule/PhabricatorKeyboardRemarkupRule.php',
|
||||
'PhabricatorKeyring' => 'applications/files/keyring/PhabricatorKeyring.php',
|
||||
'PhabricatorKeyringConfigOptionType' => 'applications/files/keyring/PhabricatorKeyringConfigOptionType.php',
|
||||
'PhabricatorLDAPAuthProvider' => 'applications/auth/provider/PhabricatorLDAPAuthProvider.php',
|
||||
|
@ -7532,6 +7533,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorJiraIssueHasObjectEdgeType' => 'PhabricatorEdgeType',
|
||||
'PhabricatorJumpNavHandler' => 'Phobject',
|
||||
'PhabricatorKeyValueDatabaseCache' => 'PhutilKeyValueCache',
|
||||
'PhabricatorKeyboardRemarkupRule' => 'PhutilRemarkupRule',
|
||||
'PhabricatorKeyring' => 'Phobject',
|
||||
'PhabricatorKeyringConfigOptionType' => 'PhabricatorConfigJSONOptionType',
|
||||
'PhabricatorLDAPAuthProvider' => 'PhabricatorAuthProvider',
|
||||
|
|
|
@ -688,6 +688,32 @@ In general:
|
|||
- The `type` option can be set to `instructions` to indicate that an element
|
||||
is asking the user to make a choice or follow specific instructions.
|
||||
|
||||
Keystrokes
|
||||
==========
|
||||
|
||||
You can use `{key ...}` to render a stylized keystroke. For example, this:
|
||||
|
||||
```
|
||||
Press {key M} to view the starmap.
|
||||
```
|
||||
|
||||
...renders this:
|
||||
|
||||
> Press {key M} to view the starmap.
|
||||
|
||||
You can also render sequences with modifier keys. This:
|
||||
|
||||
```
|
||||
Use {key command option shift 3} to take a screenshot.
|
||||
Press {key down down-right right LP} to activate the hadoken technique.
|
||||
```
|
||||
|
||||
...renders this:
|
||||
|
||||
> Use {key command option shift 3} to take a screenshot.
|
||||
> Press {key down down-right right LP} to activate the hadoken technique.
|
||||
|
||||
|
||||
= Fullscreen Mode =
|
||||
|
||||
Remarkup editors provide a fullscreen composition mode. This can make it easier
|
||||
|
|
|
@ -505,6 +505,7 @@ final class PhabricatorMarkupEngine extends Phobject {
|
|||
|
||||
$rules[] = new PhutilRemarkupDocumentLinkRule();
|
||||
$rules[] = new PhabricatorNavigationRemarkupRule();
|
||||
$rules[] = new PhabricatorKeyboardRemarkupRule();
|
||||
|
||||
if ($options['youtube']) {
|
||||
$rules[] = new PhabricatorYoutubeRemarkupRule();
|
||||
|
|
|
@ -0,0 +1,225 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorKeyboardRemarkupRule extends PhutilRemarkupRule {
|
||||
|
||||
public function getPriority() {
|
||||
return 200.0;
|
||||
}
|
||||
|
||||
public function apply($text) {
|
||||
return preg_replace_callback(
|
||||
'@{key\b((?:[^}\\\\]+|\\\\.)*)}@m',
|
||||
array($this, 'markupKeystrokes'),
|
||||
$text);
|
||||
}
|
||||
|
||||
public function markupKeystrokes(array $matches) {
|
||||
if (!$this->isFlatText($matches[0])) {
|
||||
return $matches[0];
|
||||
}
|
||||
|
||||
$keys = explode(' ', $matches[1]);
|
||||
foreach ($keys as $k => $v) {
|
||||
$v = trim($v, " \n");
|
||||
$v = preg_replace('/\\\\(.)/', '\\1', $v);
|
||||
if (!strlen($v)) {
|
||||
unset($keys[$k]);
|
||||
continue;
|
||||
}
|
||||
$keys[$k] = $v;
|
||||
}
|
||||
|
||||
$special = array(
|
||||
array(
|
||||
'name' => pht('Command'),
|
||||
'symbol' => "\xE2\x8C\x98",
|
||||
'aliases' => array(
|
||||
'cmd',
|
||||
'command',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'name' => pht('Option'),
|
||||
'symbol' => "\xE2\x8C\xA5",
|
||||
'aliases' => array(
|
||||
'opt',
|
||||
'option',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'name' => pht('Shift'),
|
||||
'symbol' => "\xE2\x87\xA7",
|
||||
'aliases' => array(
|
||||
'shift',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'name' => pht('Escape'),
|
||||
'symbol' => "\xE2\x8E\x8B",
|
||||
'aliases' => array(
|
||||
'esc',
|
||||
'escape',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'name' => pht('Up'),
|
||||
'symbol' => "\xE2\x86\x91",
|
||||
'heavy' => "\xE2\xAC\x86",
|
||||
'aliases' => array(
|
||||
'up',
|
||||
'arrow-up',
|
||||
'up-arrow',
|
||||
'north',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'name' => pht('Tab'),
|
||||
'symbol' => "\xE2\x87\xA5",
|
||||
'aliases' => array(
|
||||
'tab',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'name' => pht('Right'),
|
||||
'symbol' => "\xE2\x86\x92",
|
||||
'heavy' => "\xE2\x9E\xA1",
|
||||
'aliases' => array(
|
||||
'right',
|
||||
'right-arrow',
|
||||
'arrow-right',
|
||||
'east',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'name' => pht('Left'),
|
||||
'symbol' => "\xE2\x86\x90",
|
||||
'heavy' => "\xE2\xAC\x85",
|
||||
'aliases' => array(
|
||||
'left',
|
||||
'left-arrow',
|
||||
'arrow-left',
|
||||
'west',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'name' => pht('Down'),
|
||||
'symbol' => "\xE2\x86\x93",
|
||||
'heavy' => "\xE2\xAC\x87",
|
||||
'aliases' => array(
|
||||
'down',
|
||||
'down-arrow',
|
||||
'arrow-down',
|
||||
'south',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'name' => pht('Up Right'),
|
||||
'symbol' => "\xE2\x86\x97",
|
||||
'heavy' => "\xE2\xAC\x88",
|
||||
'aliases' => array(
|
||||
'up-right',
|
||||
'upright',
|
||||
'up-right-arrow',
|
||||
'upright-arrow',
|
||||
'arrow-up-right',
|
||||
'arrow-upright',
|
||||
'northeast',
|
||||
'north-east',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'name' => pht('Down Right'),
|
||||
'symbol' => "\xE2\x86\x98",
|
||||
'heavy' => "\xE2\xAC\x8A",
|
||||
'aliases' => array(
|
||||
'down-right',
|
||||
'downright',
|
||||
'down-right-arrow',
|
||||
'downright-arrow',
|
||||
'arrow-down-right',
|
||||
'arrow-downright',
|
||||
'southeast',
|
||||
'south-east',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'name' => pht('Down Left'),
|
||||
'symbol' => "\xE2\x86\x99",
|
||||
'heavy' => "\xE2\xAC\x8B",
|
||||
'aliases' => array(
|
||||
'down-left',
|
||||
'downleft',
|
||||
'down-left-arrow',
|
||||
'downleft-arrow',
|
||||
'arrow-down-left',
|
||||
'arrow-downleft',
|
||||
'southwest',
|
||||
'south-west',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'name' => pht('Up Left'),
|
||||
'symbol' => "\xE2\x86\x96",
|
||||
'heavy' => "\xE2\xAC\x89",
|
||||
'aliases' => array(
|
||||
'up-left',
|
||||
'upleft',
|
||||
'up-left-arrow',
|
||||
'upleft-arrow',
|
||||
'arrow-up-left',
|
||||
'arrow-upleft',
|
||||
'northwest',
|
||||
'north-west',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$map = array();
|
||||
foreach ($special as $spec) {
|
||||
foreach ($spec['aliases'] as $alias) {
|
||||
$map[$alias] = $spec;
|
||||
}
|
||||
}
|
||||
|
||||
$is_text = $this->getEngine()->isTextMode();
|
||||
|
||||
$parts = array();
|
||||
foreach ($keys as $k => $v) {
|
||||
$normal = phutil_utf8_strtolower($v);
|
||||
if (isset($map[$normal])) {
|
||||
$spec = $map[$normal];
|
||||
} else {
|
||||
$spec = array(
|
||||
'name' => null,
|
||||
'symbol' => $v,
|
||||
);
|
||||
}
|
||||
|
||||
if ($is_text) {
|
||||
$parts[] = '['.$spec['symbol'].']';
|
||||
} else {
|
||||
$parts[] = phutil_tag(
|
||||
'kbd',
|
||||
array(
|
||||
'title' => $spec['name'],
|
||||
),
|
||||
$spec['symbol']);
|
||||
}
|
||||
}
|
||||
|
||||
if ($is_text) {
|
||||
$parts = implode(' + ', $parts);
|
||||
} else {
|
||||
$glue = phutil_tag(
|
||||
'span',
|
||||
array(
|
||||
'class' => 'kbd-join',
|
||||
),
|
||||
'+');
|
||||
$parts = phutil_implode_html($glue, $parts);
|
||||
}
|
||||
|
||||
return $this->getEngine()->storeText($parts);
|
||||
}
|
||||
|
||||
}
|
|
@ -70,6 +70,11 @@
|
|||
border: 1px solid {$lightgreyborder};
|
||||
}
|
||||
|
||||
.phabricator-remarkup .kbd-join {
|
||||
padding: 0 4px;
|
||||
color: {$lightgreytext};
|
||||
}
|
||||
|
||||
.phabricator-remarkup pre.remarkup-counterexample {
|
||||
background-color: {$sh-redbackground};
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue