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