initial commit
[m6w6/m6w6.github.io] / _posts / 2009-04-10-php-commandline-highlighter.md
1 ---
2 title: PHP commandline highlighter
3 author: m6w6
4 tags:
5 - WTF
6 - PHP
7 ---
8
9 Just chewed up a command line highlighter for php code.
10 It's hacky, but it fulfills my needs.
11
12 ```php
13 class CHL {
14 protected $colors = array(
15 "start" => "0:0",
16 "stop" => "0:0",
17 "comment" => "33",
18 "default" => "30",
19 "html" => "32",
20 "keyword" => "34",
21 "string" => "31",
22 );
23 protected $encoding = "UTF-8";
24 protected $tabstops;
25 protected $colwidth;
26 private $formats;
27
28 public function __construct() {
29 if ($files = $this->setup()) {
30 foreach ($files as $file) {
31 $this->highlight(file_get_contents($file), $file);
32 }
33 } elseif ($this->select()) {
34 $this->highlight(file_get_contents("php://stdin"), "<STDIN>");
35 } else {
36 $this->usage();
37 }
38 }
39
40 public function __destruct() {
41 if ($this->tabstops) {
42 echo "\033[3g";
43 $this->tabstops = 8;
44 $this->tabstops();
45 }
46 }
47
48 protected function usage() {
49 printf("Usage:\n");
50 printf("\n");
51 printf(" %s [-e ENC] [-t TAB] [-f FILE, ...] [-c TOKEN=COLOR, ...]\n", basename($_SERVER["argv"][0]));
52 printf("\n");
53 printf(" -e ENC specify the character set of the highlighted code\n");
54 printf(" -t TAB specify the tab with\n");
55 printf(" -f FILE specify one or more files to highlight, STDIN if omitted\n");
56 printf(" -c TOKEN=COLOR specify the color code for the type of token\n");
57 printf(" possible tokens: %s\n", implode(", ",array_keys($this->colors)));
58 printf("\n");
59 exit;
60 }
61
62 protected function setup() {
63 $files = array();
64 foreach (getopt("c:e:f:t:h") as $key => $val) {
65 switch ($key) {
66 case "h":
67 $this->usage();
68 break;
69 case "c":
70 foreach ((array)$val as $col) {
71 list($type, $color) = explode("=", $col);
72 $this->colors[$type] = $color;
73 }
74 break;
75 case "e":
76 $this->encoding = current(array_reverse((array)$val));
77 break;
78 case "t":
79 if ($tabstops = (int) current(array_reverse((array)$val))) {
80 $this->tabstops = $tabstops;
81 }
82 break;
83 case "f":
84 $files = (array) $val;
85 break;
86 }
87 }
88
89 if (!$this->colwidth = getenv("COLUMNS")) {
90 if (preg_match("/columns (\d+)/", shell_exec("stty -a"), $m)) {
91 $this->colwidth = $m[1];
92 } else {
93 $this->colwidth = 80;
94 }
95 }
96
97 $this->tabstops && $this->tabstops();
98 ini_set("highlight.comment", "comment");
99 ini_set("highlight.default", "default");
100 ini_set("highlight.html", "html");
101 ini_set("highlight.keyword", "keyword");
102 ini_set("highlight.string", "string");
103 $this->formats = array(
104 // get rid of html
105 "/\R/" => "",
106 "/<br \/>/" => "\n",
107 "/<\/span>/" => "",
108 "/(&nbsp;){4}/" => "\t",
109 "/&nbsp;/" => " ",
110 // convert colors
111 "/<span style=\"color: comment\">/" => $this->color("comment"),
112 "/<span style=\"color: default\">/" => $this->color("default"),
113 "/<span style=\"color: html\">/" => $this->color("html"),
114 "/<span style=\"color: keyword\">/" => $this->color("keyword"),
115 "/<span style=\"color: string\">/" => $this->color("string"),
116 // fix colors before newline
117 #"/((\033\[\d+m)+)([[:punct:][:space:]]*)(\r?\n)/s" => "\$1\$3\$4\$1",
118 // start/stop
119 "/<code>/" => $this->color("start"),
120 "/<\/code>/" => $this->color("stop", "", PHP_EOL),
121 );
122 return $files;
123 }
124
125 protected function select() {
126 $r = $w = $e = array();
127 $r[] = STDIN;
128 if (stream_select($r, $w, $e, 0, 100) && $r[0]) {
129 return true;
130 }
131 return false;
132 }
133
134 protected function tabstops() {
135 $colw = $this->colwidth;
136 $tabs = str_repeat(" ", $this->tabstops) . "\033H";
137 $tabs = str_repeat($tabs, $colw/$this->tabstops);
138 echo $tabs . "\r";
139 }
140
141 protected function color($type, $prepend = "", $append = "") {
142 return $prepend . "\033[" . implode("m\033[", explode(":", $this->colors[$type])) . "m" . $append;
143 }
144
145 protected function highlight($code, $name) {
146 echo "## Syntax highlighted code of $name:\n";
147 echo html_entity_decode(
148 preg_replace(
149 array_keys($this->formats),
150 array_values($this->formats),
151 highlight_string($code, true)
152 ),
153 ENT_QUOTES,
154 $this->encoding
155 );
156 echo PHP_EOL;
157 }
158 }
159 ```
160
161 Cheers-
162