Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/infrastructure/markup/syntax/highlighter/PhutilDivinerSyntaxHighlighter.php
12242 views
1
<?php
2
3
/**
4
* Simple syntax highlighter for the ".diviner" format, which is just Remarkup
5
* with a specific ruleset. This should also work alright for Remarkup.
6
*/
7
final class PhutilDivinerSyntaxHighlighter extends Phobject {
8
9
private $config = array();
10
private $replaceClass;
11
12
public function setConfig($key, $value) {
13
$this->config[$key] = $value;
14
return $this;
15
}
16
17
public function getHighlightFuture($source) {
18
$source = phutil_escape_html($source);
19
20
// This highlighter isn't perfect but tries to do an okay job at getting
21
// some of the basics at least. There's lots of room for improvement.
22
23
$blocks = explode("\n\n", $source);
24
foreach ($blocks as $key => $block) {
25
if (preg_match('/^[^ ](?! )/m', $block)) {
26
$blocks[$key] = $this->highlightBlock($block);
27
}
28
}
29
$source = implode("\n\n", $blocks);
30
31
$source = phutil_safe_html($source);
32
return new ImmediateFuture($source);
33
}
34
35
private function highlightBlock($source) {
36
// Highlight "@{class:...}" links to other documentation pages.
37
$source = $this->highlightPattern('/@{([\w@]+?):([^}]+?)}/', $source, 'nc');
38
39
// Highlight "@title", "@group", etc.
40
$source = $this->highlightPattern('/^@(\w+)/m', $source, 'k');
41
42
// Highlight bold, italic and monospace.
43
$source = $this->highlightPattern('@\\*\\*(.+?)\\*\\*@s', $source, 's');
44
$source = $this->highlightPattern('@(?<!:)//(.+?)//@s', $source, 's');
45
$source = $this->highlightPattern(
46
'@##([\s\S]+?)##|\B`(.+?)`\B@',
47
$source,
48
's');
49
50
// Highlight stuff that looks like headers.
51
$source = $this->highlightPattern('/^=(.*)$/m', $source, 'nv');
52
53
return $source;
54
}
55
56
private function highlightPattern($regexp, $source, $class) {
57
$this->replaceClass = $class;
58
$source = preg_replace_callback(
59
$regexp,
60
array($this, 'replacePattern'),
61
$source);
62
63
return $source;
64
}
65
66
public function replacePattern($matches) {
67
68
// NOTE: The goal here is to make sure a <span> never crosses a newline.
69
70
$content = $matches[0];
71
$content = explode("\n", $content);
72
foreach ($content as $key => $line) {
73
$content[$key] =
74
'<span class="'.$this->replaceClass.'">'.
75
$line.
76
'</span>';
77
}
78
return implode("\n", $content);
79
}
80
81
}
82
83