<?php
const HIGHLIGHTJS_DIR = '.highlightjs'; // https://highlightjs.org/
const FILE_EXTENSIONS = array(
'bat' => 'language-dos',
'cpp' => 'language-cpp',
'css' => 'language-css',
'gcode' => 'language-gcode',
'geojson' => 'language-json',
'hpp' => 'language-cpp',
'html' => 'language-xml',
'ini' => 'language-ini',
'java' => 'language-java',
'js' => 'language-javascript',
'json' => 'language-json',
'md' => 'language-markdown',
'php' => 'language-php',
'phps' => 'language-php',
'py' => 'language-python',
'sh' => 'language-bash',
'sql' => 'language-sql',
'svg' => 'language-xml',
'tex' => 'language-latex',
'txt' => 'language-plaintext',
'xml' => 'language-xml',
'xspf' => 'language-xml');
const STYLES = array(
'ascetic',
'androidstudio',
'dark',
'default',
'default-auto',
'github',
'github-auto',
'github-dark',
'qtcreator-auto',
'qtcreator-dark',
'qtcreator-light',
'vs',
'vs2015',
'xcode');
/**
* @author Gernot WALZL
*/
class HighlightHTML {
function println($msg) {
print($msg."\n");
}
function print_head($filename='', $style='') {
$this->println('<!DOCTYPE html>');
$this->println('<html lang="en">');
$this->println('<head>');
$this->println('<meta charset="utf-8" />');
$this->println('<meta name="viewport" '.
'content="width=device-width, initial-scale=1.0" />');
if (empty($filename)) {
$this->println('<title>Syntax Highlighting</title>');
} else {
$this->println('<title>'.basename($filename).'</title>');
if (!empty($style)) {
$stylesheet = HIGHLIGHTJS_DIR.'/styles/'.$style.'.min.css';
$href = $stylesheet.'?mtime='.filemtime($stylesheet);
$this->println('<link rel="stylesheet" href="'.$href.'" />');
$script = HIGHLIGHTJS_DIR.'/highlight.min.js';
$src = $script.'?mtime='.filemtime($script);
$integrity = 'sha256-'.base64_encode(
hash_file('sha256', $script, true));
$this->println('<script src="'.$src.'" '.
'integrity="'.$integrity.'"></script>');
$this->println('<script>hljs.highlightAll();</script>');
}
}
$this->println('</head>');
if (empty($filename) or empty($style)) {
$this->println('<body>');
} else {
$this->println('<body class="hljs" style="margin: 0;">');
}
}
function print_foot() {
$this->println('</body>');
$this->println('</html>');
}
function print_form($filename='', $style_selected='') {
if (empty($filename)) {
$filename = basename(__FILE__);
}
$this->println('<form method="get" action="'.$_SERVER['PHP_SELF'].'">');
$this->println('<table>');
$this->println('<tr>');
$this->println('<td><label for="filename">Filename:</label></td>');
$this->println('<td><input type="text" id="filename" name="filename" '.
'value="'.htmlentities($filename).'" /></td>');
$this->println('</tr>');
$this->println('<tr>');
$this->println('<td><label for="style">Style:</label></td>');
$this->println('<td><select id="style" name="style">');
$this->println('<option value="">nohighlight</option>');
foreach (STYLES as $style) {
if ($style == $style_selected) {
$this->println('<option value="'.$style.'" selected>'.
$style.'</option>');
} else {
$this->println('<option value="'.$style.'">'.
$style.'</option>');
}
}
$this->println('</select></td>');
$this->println('</tr>');
$this->println('</table>');
$this->println('<p><input type="submit" value="Show Source" /></p>');
$this->println('</form>');
}
function print_info() {
$this->println('<h1>Syntax Highlighting</h1>');
$this->println('<p>Show source code with highlighted syntax<br />');
$this->println('Uses <a href="https://highlightjs.org/" target="_blank">'.
'highlight.js</a></p>');
}
function print_error() {
$this->println('<p><strong>Error:</strong> '.
'The given filename is not valid.</p>');
}
function print_supported_files() {
$this->println('<h2>Supported Files</h2>');
$this->println('<table>');
$this->println('<tr>');
$this->println('<th>Extension</th>');
$this->println('<th>Language</th>');
$this->println('</tr>');
foreach (FILE_EXTENSIONS as $ext => $language) {
$this->println('<tr>');
$this->println('<td>'.$ext.'</td>');
$this->println('<td>'.str_replace(
'language-', '', $language).'</td>');
$this->println('</tr>');
}
$this->println('</table>');
}
function print_code($filename) {
$language = 'nohighlight';
$ext = pathinfo($filename, PATHINFO_EXTENSION);
if (array_key_exists($ext, FILE_EXTENSIONS)) {
$language = FILE_EXTENSIONS[$ext];
}
print('<pre style="margin: 0;">'.
'<code class="'.$language.'" style="min-width: fit-content;">');
$filecontents = file_get_contents($filename);
print(htmlentities($filecontents));
$this->println('</code></pre>');
}
}
function is_valid_filename($filename) {
$result = false;
if (!empty($filename)) {
if (!strstr($filename, '..')) {
$full_filename = dirname(__FILE__).'/'.$filename;
if (is_file($full_filename) and is_readable($full_filename)) {
$result = true;
}
}
}
return $result;
}
function is_allowed_filename($filename) {
$result = false;
$forbidden = array('wp-config.php', 'config.inc.php');
if (!empty($filename)) {
$base = basename($filename);
if (substr($base, 0, 1) != '.') {
if (!in_array($base, $forbidden)) {
$ext = pathinfo($filename, PATHINFO_EXTENSION);
if (array_key_exists($ext, FILE_EXTENSIONS)) {
$result = true;
}
}
}
}
return $result;
}
$filename = '';
if (!empty($_GET['filename'])) {
$filename = $_GET['filename'];
}
$style = 'github-auto';
if (isset($_GET['style'])) {
$style = '';
if (in_array($_GET['style'], STYLES)) {
$style = $_GET['style'];
}
}
$html_highlight = new HighlightHTML();
if (is_valid_filename($filename) and is_allowed_filename($filename)) {
$html_highlight->print_head($filename, $style);
$html_highlight->print_code(dirname(__FILE__).'/'.$filename);
} else {
$html_highlight->print_head();
$html_highlight->print_info();
if (!empty($filename)) {
$html_highlight->print_error();
}
$html_highlight->print_form($filename, $style);
$html_highlight->print_supported_files();
}
$html_highlight->print_foot();
?>