Created
August 8, 2018 11:28
-
-
Save kingschnulli/f10c582c6a283578fc76a27908f6c17c to your computer and use it in GitHub Desktop.
Grunt runner for gxid e-shop flow theme
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Config - adjust as needed | |
*/ | |
// Path to node download | |
$nodeUrl = 'https://nodejs.org/dist/v8.11.3/node-v8.11.3-linux-x64.tar.xz'; | |
// Id of your child theme | |
$customTheme = 'aufkleber'; | |
/** | |
* End of config | |
*/ | |
$basePath = realpath(dirname(__FILE__)) . '/'; | |
if(!file_exists('./nodejs/bin/node')){ | |
// Download nodejs | |
mkdir('./nodejs'); | |
$options = array( | |
CURLOPT_FILE => fopen('./nodejs/node.tar.xz', 'w'), | |
CURLOPT_TIMEOUT => 28800, // set this to 8 hours so we dont timeout on big files | |
CURLOPT_URL => $nodeUrl | |
); | |
$ch = curl_init(); | |
curl_setopt_array($ch, $options); | |
curl_exec($ch); | |
curl_close($ch); | |
// Extract nodejs | |
exec('cd ./nodejs/ && tar -xf ./node.tar.xz'); | |
// Delete zip | |
exec('rm ./nodejs/node.tar.xz'); | |
// Move folder contents | |
exec('mv ./nodejs/node-v8.11.3-linux-x64/* ./nodejs/'); | |
// Remove old folder | |
exec('rmdir ./nodejs/node-v8.11.3-linux-x64/'); | |
// Secure folder | |
file_put_contents('./nodejs/.htaccess', 'deny from all'); | |
} | |
if (!file_exists('./Application/views/__grunt__'.$customTheme.'/')) { | |
// Create grunt theme folder | |
exec('mkdir ./Application/views/__grunt__'.$customTheme.'/'); | |
// Copy flow to custom | |
exec('cp -r ./Application/views/flow/* ./Application/views/__grunt__'.$customTheme.'/'); | |
// Install grunt-cli locally | |
exec('cd ./Application/views/__grunt__'.$customTheme.'/ && ../../../nodejs/bin/node ../../../nodejs/bin/npm install grunt-cli --save-dev'); | |
// install flow grunt plugins | |
exec('cd ./Application/views/__grunt__'.$customTheme.'/ && ../../../nodejs/bin/node ../../../nodejs/bin/npm install --save-dev'); | |
// add grunt script to package.json | |
$packageJson = file_get_contents('./Application/views/__grunt__'.$customTheme.'/package.json'); | |
$package = json_decode($packageJson); | |
$package->scripts->build = "grunt"; | |
file_put_contents('./Application/views/__grunt__'.$customTheme.'/package.json', json_encode($package)); | |
} | |
// Copy custom stuff to grunt theme folder | |
exec('cp -r ./Application/views/'.$customTheme.'/* ./Application/views/__grunt__'.$customTheme.'/'); | |
// Run grunt | |
exec('export PATH="$PATH:'.$basePath.'nodejs/bin/" && cd '.$basePath.'Application/views/__grunt__'.$customTheme.'/ && npm run-script build', $out); | |
// Copy files | |
exec('cp -r ./Application/views/__grunt__'.$customTheme.'/out/flow/* ./out/'.$customTheme.'/'); | |
// Join output - the rest is just ANSI to HTML stuff | |
$output = implode("\n", $out); | |
/** | |
* Converts an ANSI text to HTML5. | |
*/ | |
class AnsiToHtmlConverter | |
{ | |
protected $theme; | |
protected $charset; | |
protected $inlineStyles; | |
protected $inlineColors; | |
protected $colorNames; | |
public function __construct(Theme $theme = null, $inlineStyles = true, $charset = 'UTF-8') | |
{ | |
$this->theme = null === $theme ? new Theme() : $theme; | |
$this->inlineStyles = $inlineStyles; | |
$this->charset = $charset; | |
$this->inlineColors = $this->theme->asArray(); | |
$this->colorNames = array( | |
'black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white', | |
'', '', | |
'brblack', 'brred', 'brgreen', 'bryellow', 'brblue', 'brmagenta', 'brcyan', 'brwhite', | |
); | |
} | |
public function convert($text) | |
{ | |
// remove cursor movement sequences | |
$text = preg_replace('#\e\[(K|s|u|2J|2K|\d+(A|B|C|D|E|F|G|J|K|S|T)|\d+;\d+(H|f))#', '', $text); | |
// remove character set sequences | |
$text = preg_replace('#\e(\(|\))(A|B|[0-2])#', '', $text); | |
$text = htmlspecialchars($text, PHP_VERSION_ID >= 50400 ? ENT_QUOTES | ENT_SUBSTITUTE : ENT_QUOTES, $this->charset); | |
// carriage return | |
$text = preg_replace('#^.*\r(?!\n)#m', '', $text); | |
$tokens = $this->tokenize($text); | |
// a backspace remove the previous character but only from a text token | |
foreach ($tokens as $i => $token) { | |
if ('backspace' == $token[0]) { | |
$j = $i; | |
while (--$j >= 0) { | |
if ('text' == $tokens[$j][0] && strlen($tokens[$j][1]) > 0) { | |
$tokens[$j][1] = substr($tokens[$j][1], 0, -1); | |
break; | |
} | |
} | |
} | |
} | |
$html = ''; | |
foreach ($tokens as $token) { | |
if ('text' == $token[0]) { | |
$html .= $token[1]; | |
} elseif ('color' == $token[0]) { | |
$html .= $this->convertAnsiToColor($token[1]); | |
} | |
} | |
if ($this->inlineStyles) { | |
$html = sprintf('<span style="background-color: %s; color: %s">%s</span>', $this->inlineColors['black'], $this->inlineColors['white'], $html); | |
} else { | |
$html = sprintf('<span class="ansi_color_bg_black ansi_color_fg_white">%s</span>', $html); | |
} | |
// remove empty span | |
$html = preg_replace('#<span[^>]*></span>#', '', $html); | |
return $html; | |
} | |
public function getTheme() | |
{ | |
return $this->theme; | |
} | |
protected function convertAnsiToColor($ansi) | |
{ | |
$bg = 0; | |
$fg = 7; | |
$as = ''; | |
if ('0' != $ansi && '' != $ansi) { | |
$options = explode(';', $ansi); | |
foreach ($options as $option) { | |
if ($option >= 30 && $option < 38) { | |
$fg = $option - 30; | |
} elseif ($option >= 40 && $option < 48) { | |
$bg = $option - 40; | |
} elseif (39 == $option) { | |
$fg = 7; | |
} elseif (49 == $option) { | |
$bg = 0; | |
} | |
} | |
// options: bold => 1, underscore => 4, blink => 5, reverse => 7, conceal => 8 | |
if (in_array(1, $options)) { | |
$fg += 10; | |
$bg += 10; | |
} | |
if (in_array(4, $options)) { | |
$as = '; text-decoration: underline'; | |
} | |
if (in_array(7, $options)) { | |
$tmp = $fg; | |
$fg = $bg; | |
$bg = $tmp; | |
} | |
} | |
if ($this->inlineStyles) { | |
return sprintf('</span><span style="background-color: %s; color: %s%s">', $this->inlineColors[$this->colorNames[$bg]], $this->inlineColors[$this->colorNames[$fg]], $as); | |
} else { | |
return sprintf('</span><span class="ansi_color_bg_%s ansi_color_fg_%s">', $this->colorNames[$bg], $this->colorNames[$fg]); | |
} | |
} | |
protected function tokenize($text) | |
{ | |
$tokens = array(); | |
preg_match_all("/(?:\e\[(.*?)m|(\x08))/", $text, $matches, PREG_OFFSET_CAPTURE); | |
$offset = 0; | |
foreach ($matches[0] as $i => $match) { | |
if ($match[1] - $offset > 0) { | |
$tokens[] = array('text', substr($text, $offset, $match[1] - $offset)); | |
} | |
$tokens[] = array("\x08" == $match[0] ? 'backspace' : 'color', $matches[1][$i][0]); | |
$offset = $match[1] + strlen($match[0]); | |
} | |
if ($offset < strlen($text)) { | |
$tokens[] = array('text', substr($text, $offset)); | |
} | |
return $tokens; | |
} | |
} | |
class Theme | |
{ | |
public function asCss($prefix = 'ansi_color') | |
{ | |
$css = array(); | |
foreach ($this->asArray() as $name => $color) { | |
$css[] = sprintf('.%s_fg_%s { color: %s }', $prefix, $name, $color); | |
$css[] = sprintf('.%s_bg_%s { background-color: %s }', $prefix, $name, $color); | |
} | |
return implode("\n", $css); | |
} | |
public function asArray() | |
{ | |
return array( | |
'black' => 'black', | |
'red' => 'darkred', | |
'green' => 'green', | |
'yellow' => 'yellow', | |
'blue' => 'blue', | |
'magenta' => 'darkmagenta', | |
'cyan' => 'cyan', | |
'white' => 'white', | |
'brblack' => 'black', | |
'brred' => 'red', | |
'brgreen' => 'lightgreen', | |
'bryellow' => 'lightyellow', | |
'brblue' => 'lightblue', | |
'brmagenta' => 'magenta', | |
'brcyan' => 'lightcyan', | |
'brwhite' => 'white', | |
); | |
} | |
} | |
$converter = new AnsiToHtmlConverter(); | |
$html = $converter->convert($output); | |
?> | |
<html> | |
<body style="background-color: black;"> | |
<pre style="background-color: black; overflow: auto; padding: 10px 15px; font-family: monospace;" | |
><?php echo $html ?></pre> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment