1
0
Fork 0
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:
epriestley 2016-09-07 08:19:14 -07:00
parent b7e51877c3
commit 5f43abd7ef
6 changed files with 262 additions and 3 deletions

View file

@ -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',

View file

@ -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',

View file

@ -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

View file

@ -505,6 +505,7 @@ final class PhabricatorMarkupEngine extends Phobject {
$rules[] = new PhutilRemarkupDocumentLinkRule();
$rules[] = new PhabricatorNavigationRemarkupRule();
$rules[] = new PhabricatorKeyboardRemarkupRule();
if ($options['youtube']) {
$rules[] = new PhabricatorYoutubeRemarkupRule();

View file

@ -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);
}
}

View file

@ -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};
}