1 |
<?php |
2 |
|
3 |
define(ASHIGHLIGHT_LANG_ROOT,"/usr/share/highlight/langDefs"); |
4 |
|
5 |
class ASHighlight{ |
6 |
|
7 |
function __construct($dir="/tmp",$default_lang="py"){ |
8 |
$this->env=array(); |
9 |
$this->dir=$dir; |
10 |
$this->encoding="ascii"; |
11 |
$this->line_numbers=false; |
12 |
$this->default_lang=$default_lang; |
13 |
} |
14 |
|
15 |
function set_encoding($encoding="UTF-8"){ |
16 |
$this->encoding=$encoding; |
17 |
} |
18 |
|
19 |
function enable_line_numbers(){ |
20 |
$this->line_numbers = true; |
21 |
} |
22 |
function disable_line_numbers(){ |
23 |
$this->line_numbers = false; |
24 |
} |
25 |
|
26 |
function start_line_numbers_at($start_line){ |
27 |
$this->start_line = int($start_line); |
28 |
} |
29 |
|
30 |
function set_tab_width($tabwidth){ |
31 |
$this->tabwidth=int($tabwidth); |
32 |
} |
33 |
|
34 |
function parse_code($text,$lang=""){ |
35 |
$descriptorspec = array( |
36 |
0 => array("pipe", "r"), // stdin is a pipe that the child will read from |
37 |
1 => array("pipe", "w"), // stdout is a pipe that the child will write to |
38 |
2 => array("pipe", "w") // stderr is another pipe that the child (might) write to |
39 |
); |
40 |
|
41 |
if(!$lang)$lang=$this->default_lang; |
42 |
|
43 |
$cmd = "highlight --fragment" |
44 |
." --syntax=".escapeshellarg($lang); |
45 |
|
46 |
if($this->line_numbers){ |
47 |
$cmd.=" --linenumbers"; |
48 |
if(isset($this->start_line)){ |
49 |
$cmd.=" --line-number-start=".$this->start_line; |
50 |
} |
51 |
} |
52 |
|
53 |
if($this->tabwidth)$cmd.=" --replace-tabs=".$this->tabwidth; |
54 |
|
55 |
$css = $this->dir . "/" . "highlight.css"; |
56 |
$cmd.=" --style-outfile=".escapeshellarg($css); |
57 |
if(file_exists($css)){ |
58 |
$this->error=-888; |
59 |
$this->errmsg="'highlight.css' file already exists in ".$this->dir; |
60 |
} |
61 |
|
62 |
if(!$this->env)$this->env=array(); |
63 |
|
64 |
$process = proc_open($cmd, $descriptorspec, $pipes, $this->dir, $this->env); |
65 |
|
66 |
if(is_resource($process)) { |
67 |
// $pipes now looks like this: |
68 |
// 0 => writeable handle connected to child stdin |
69 |
// 1 => readable handle connected to child stdout |
70 |
// Any error output will be appended to /tmp/error-output.txt |
71 |
|
72 |
fwrite($pipes[0], $text); |
73 |
fclose($pipes[0]); |
74 |
|
75 |
$out = stream_get_contents($pipes[1]); |
76 |
fclose($pipes[1]); |
77 |
|
78 |
$err = stream_get_contents($pipes[2]); |
79 |
fclose($pipes[2]); |
80 |
|
81 |
// It is important that you close any pipes before calling |
82 |
// proc_close in order to avoid a deadlock |
83 |
$this->error = proc_close($process); |
84 |
|
85 |
if(!$this->error){ |
86 |
if(file_exists($css)){ |
87 |
$this->stylesheet = file_get_contents($css); |
88 |
unlink($css); |
89 |
return $out; |
90 |
}else{ |
91 |
$this->error=-777; |
92 |
$this->stylesheet="kwa{font:bold}"; |
93 |
$this->errmsg="'$css' was not created by $cmd (dir=$this->dir)"; |
94 |
return $out; |
95 |
} |
96 |
}else{ |
97 |
$this->errmsg = $err; |
98 |
} |
99 |
}else{ |
100 |
$this->error = -999; |
101 |
$this->errmsg="Process '$cmd' failed to start?"; |
102 |
} |
103 |
} |
104 |
|
105 |
function get_stylesheet(){ |
106 |
return $this->stylesheet; |
107 |
} |
108 |
} |
109 |
|
110 |
?> |