import
[web.mtrack] / inc / syntax.php
1 <?php # vim:ts=2:sw=2:et:
2 /* For licensing and copyright terms, see the file named LICENSE */
3
4 class MTrackSyntaxHighlight {
5   static $schemes = array(
6     '' => 'No syntax highlighting',
7     'wezterm' => "Wez's Terminal",
8     'zenburn' => "Zenburn",
9     'vibrant-ink' => "Vibrant Ink",
10   );
11   static $lang_by_ext = array(
12       'c' => 'cpp',
13       'cc' => 'cpp',
14       'cpp' => 'cpp',
15       'h' => 'cpp',
16       'hpp' => 'cpp',
17       'icl' => 'cpp',
18       'ipp' => 'cpp',
19       'css' => 'css',
20       'php' => 'php',
21       'php3' => 'php',
22       'php4' => 'php',
23       'php5' => 'php',
24       'phtml' => 'php',
25       'pl' => 'perl',
26       'pm' => 'perl',
27       't' => 'perl',
28       'bash' => 'shell',
29       'sh' => 'shell',
30       'js' => 'javascript',
31       'json' => 'javascript',
32       'vb' => 'vb',
33       'xml' => 'xml',
34       'xsl' => 'xml',
35       'xslt' => 'xml',
36       'xsd' => 'xml',
37       'html' => 'xml',
38       'diff' => 'diff',
39       'patch' => 'diff',
40       'wiki' => 'wiki',
41     );
42   static $langs = array(
43     '' => 'No particular file type',
44     'cpp' => 'C/C++',
45     'css' => 'CSS (Cascading Style Sheet)',
46     'php' => 'PHP',
47     'perl' => 'Perl',
48     'shell' => 'Shell script',
49     'javascript' => 'Javascript',
50     'vb' => 'Visual Basic',
51     'xml' => 'HTML, XML, XSL',
52     'wiki' => 'Wiki Markup',
53     'diff' => 'Diff/Patch',
54   );
55
56   static function inferFileTypeFromContents($data) {
57     if (preg_match("/vim:.*ft=(\S+)/", $data, $M)) {
58       return $M[1];
59     }
60     if (preg_match("/^#!.*env\s+(\S+)/", $data, $M)) {
61       return $M[1];
62     }
63     if (preg_match("/^#!\s*(\S+)/", $data, $M)) {
64       return basename($M[1]);
65     }
66     return null;
67   }
68
69   static function highlightSource($data, $type = null, $filename = null, $line_numbers = false) {
70     if ($type === null) {
71       $type = self::inferFileTypeFromContents($data);
72       if ($type === null && $filename !== null) {
73         if (preg_match("/\.([^.]+)$/", $filename, $M)) {
74           $ext = strtolower($M[1]);
75           if (isset(self::$lang_by_ext[$ext])) {
76             $type = self::$lang_by_ext[$ext];
77           }
78         }
79       }
80     }
81     if ($type == 'diff') {
82       return mtrack_diff($data);
83     }
84     if (strlen($type) && isset(self::$langs[$type])) {
85       require_once dirname(__FILE__) . '/hyperlight/hyperlight.php';
86       $hl = new Hyperlight($type);
87       $hdata = $hl->render($data);
88     } else {
89       $hdata = htmlentities($data);
90     }
91     if (!$line_numbers) {
92       return "<span class='source-code wezterm'>$hdata</span>";
93     }
94     $lines = preg_split("/\r?\n/", $data);
95     $html = <<<HTML
96 <table class='codeann'>
97   <tr>
98     <th class='line'>line</th>
99     <th class='code'>code</th>
100   </tr>
101 HTML;
102     $nlines = count($lines);
103     for ($i = 1; $i <= $nlines; $i++) {
104       $html .= "<tr><td class='line'><a name='l$i'></a><a href='#l$i'>$i</a></td>";
105       if ($i == 1) {
106         $html .= "<td rowspan='$nlines' width='100%' class='source-code wezterm'>$hdata</td>";
107       }
108       $html .= "</tr>\n";
109     }
110     return $html . "</table>\n";
111   }
112
113   static function getSchemeSelect($selected = 'wezterm') {
114     $html = <<<HTML
115 <select class='select-hl-scheme'>
116 HTML;
117     foreach (self::$schemes as $k => $v) {
118       $sel = $selected == $k ? " selected" : '';
119       $html .= "<option value='$k'$sel>" .
120         htmlentities($v, ENT_QUOTES, 'utf-8') .
121         "</option>\n";
122     }
123     return $html . "</select>";
124   }
125
126   static function getLangSelect($name, $value) {
127     return mtrack_select_box($name, self::$langs, $value);
128   }
129
130 }
131