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