Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/infrastructure/markup/markuprule/PhutilRemarkupAnchorRule.php
12241 views
1
<?php
2
3
final class PhutilRemarkupAnchorRule extends PhutilRemarkupRule {
4
5
public function getPriority() {
6
return 200.0;
7
}
8
9
public function apply($text) {
10
return preg_replace_callback(
11
'/{anchor\s+#([^\s}]+)}/s',
12
array($this, 'markupAnchor'),
13
$text);
14
}
15
16
protected function markupAnchor(array $matches) {
17
$engine = $this->getEngine();
18
19
if ($engine->isTextMode()) {
20
return null;
21
}
22
23
if ($engine->isHTMLMailMode()) {
24
return null;
25
}
26
27
if ($engine->isAnchorMode()) {
28
return null;
29
}
30
31
if (!$this->isFlatText($matches[0])) {
32
return $matches[0];
33
}
34
35
if (!self::isValidAnchorName($matches[1])) {
36
return $matches[0];
37
}
38
39
$tag_view = phutil_tag(
40
'a',
41
array(
42
'name' => $matches[1],
43
),
44
'');
45
46
return $this->getEngine()->storeText($tag_view);
47
}
48
49
public static function isValidAnchorName($anchor_name) {
50
$normal_anchor = self::normalizeAnchor($anchor_name);
51
52
if ($normal_anchor === $anchor_name) {
53
return true;
54
}
55
56
return false;
57
}
58
59
public static function normalizeAnchor($anchor) {
60
// Replace all latin characters which are not "a-z" or "0-9" with "-".
61
// Preserve other characters, since non-latin letters and emoji work
62
// fine in anchors.
63
$anchor = preg_replace('/[\x00-\x2F\x3A-\x60\x7B-\x7F]+/', '-', $anchor);
64
$anchor = trim($anchor, '-');
65
66
return $anchor;
67
}
68
69
}
70
71