Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/infrastructure/parser/PhutilPygmentizeParser.php
12241 views
1
<?php
2
3
/**
4
* Parser that converts `pygmetize` output or similar HTML blocks from "class"
5
* attributes to "style" attributes.
6
*/
7
final class PhutilPygmentizeParser extends Phobject {
8
9
private $map = array();
10
11
public function setMap(array $map) {
12
$this->map = $map;
13
return $this;
14
}
15
16
public function getMap() {
17
return $this->map;
18
}
19
20
public function parse($block) {
21
$class_look = 'class="';
22
$class_len = strlen($class_look);
23
24
$class_start = null;
25
26
$map = $this->map;
27
28
$len = strlen($block);
29
$out = '';
30
$mode = 'text';
31
for ($ii = 0; $ii < $len; $ii++) {
32
$c = $block[$ii];
33
switch ($mode) {
34
case 'text':
35
// We're in general text between tags, and just passing characers
36
// through unmodified.
37
if ($c == '<') {
38
$mode = 'tag';
39
}
40
$out .= $c;
41
break;
42
case 'tag':
43
// We're inside a tag, and looking for `class="` so we can rewrite
44
// it.
45
if ($c == '>') {
46
$mode = 'text';
47
}
48
if ($c == 'c') {
49
if (!substr_compare($block, $class_look, $ii, $class_len)) {
50
$mode = 'class';
51
$ii += $class_len;
52
$class_start = $ii;
53
}
54
}
55
56
if ($mode != 'class') {
57
$out .= $c;
58
}
59
break;
60
case 'class':
61
// We're inside a `class="..."` tag, and looking for the ending quote
62
// so we can replace it.
63
if ($c == '"') {
64
$class = substr($block, $class_start, $ii - $class_start);
65
66
// If this class is present in the map, rewrite it into an inline
67
// style attribute.
68
if (isset($map[$class])) {
69
$out .= 'style="'.phutil_escape_html($map[$class]).'"';
70
} else {
71
$out .= 'class="'.$class.'"';
72
}
73
74
$mode = 'tag';
75
}
76
break;
77
}
78
}
79
80
return $out;
81
}
82
83
}
84
85