first commit
This commit is contained in:
252
class/sacy/ext-translators.php
Normal file
252
class/sacy/ext-translators.php
Normal file
@@ -0,0 +1,252 @@
|
||||
<?php
|
||||
|
||||
namespace sacy;
|
||||
|
||||
abstract class ExternalProcessor
|
||||
{
|
||||
abstract protected function getCommandLine($filename, $opts = []);
|
||||
|
||||
public function transform($in, $filename, $opts = [])
|
||||
{
|
||||
$s = [
|
||||
0 => ['pipe', 'r'],
|
||||
1 => ['pipe', 'w'],
|
||||
2 => ['pipe', 'w'],
|
||||
];
|
||||
$cmd = $this->getCommandLine($filename, $opts);
|
||||
$p = proc_open($cmd, $s, $pipes, getcwd());
|
||||
if (!is_resource($p)) {
|
||||
throw new \Exception("Failed to execute {$cmd}");
|
||||
}
|
||||
|
||||
fwrite($pipes[0], $in);
|
||||
fclose($pipes[0]);
|
||||
|
||||
$out = stream_get_contents($pipes[1]);
|
||||
$err = stream_get_contents($pipes[2]);
|
||||
|
||||
fclose($pipes[1]);
|
||||
fclose($pipes[2]);
|
||||
|
||||
$r = proc_close($p);
|
||||
|
||||
if ($r != 0) {
|
||||
throw new \Exception("Command returned {$r}: {$out} {$err}");
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
}
|
||||
|
||||
class ExternalProcessorRegistry
|
||||
{
|
||||
private static $transformers;
|
||||
private static $compressors;
|
||||
|
||||
public static function registerTransformer($type, $cls)
|
||||
{
|
||||
self::$transformers[$type] = $cls;
|
||||
}
|
||||
|
||||
public static function registerCompressor($type, $cls)
|
||||
{
|
||||
self::$compressors[$type] = $cls;
|
||||
}
|
||||
|
||||
private static function lookup($type, $in)
|
||||
{
|
||||
return (isset($in[$type])) ? new $in[$type]() : null;
|
||||
}
|
||||
|
||||
public static function typeIsSupported($type)
|
||||
{
|
||||
return isset(self::$transformers[$type])
|
||||
|| isset(self::$compressors[$type]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @static
|
||||
*
|
||||
* @param $type string mime type of input
|
||||
*
|
||||
* @return ExternalProcessor
|
||||
*/
|
||||
public static function getTransformerForType($type)
|
||||
{
|
||||
return self::lookup($type, self::$transformers);
|
||||
}
|
||||
|
||||
/**
|
||||
* @static
|
||||
*
|
||||
* @param $type string mime type of input
|
||||
*
|
||||
* @return ExternalProcessor
|
||||
*/
|
||||
public static function getCompressorForType($type)
|
||||
{
|
||||
return self::lookup($type, self::$compressors);
|
||||
}
|
||||
}
|
||||
|
||||
class ProcessorUglify extends ExternalProcessor
|
||||
{
|
||||
protected function getCommandLine($filename, $opts = [])
|
||||
{
|
||||
if (!is_executable(SACY_COMPRESSOR_UGLIFY)) {
|
||||
throw new Exception('SACY_COMPRESSOR_UGLIFY defined but not executable');
|
||||
}
|
||||
|
||||
return SACY_COMPRESSOR_UGLIFY;
|
||||
}
|
||||
}
|
||||
|
||||
class ProcessorCoffee extends ExternalProcessor
|
||||
{
|
||||
protected function getCommandLine($filename, $opts = [])
|
||||
{
|
||||
if (!is_executable(SACY_TRANSFORMER_COFFEE)) {
|
||||
throw new Exception('SACY_TRANSFORMER_COFFEE defined but not executable');
|
||||
}
|
||||
|
||||
return sprintf('%s -c -s', SACY_TRANSFORMER_COFFEE);
|
||||
}
|
||||
}
|
||||
|
||||
class ProcessorEco extends ExternalProcessor
|
||||
{
|
||||
protected function getType()
|
||||
{
|
||||
return 'text/x-eco';
|
||||
}
|
||||
|
||||
protected function getCommandLine($filename, $opts = [])
|
||||
{
|
||||
if (!is_executable(SACY_TRANSFORMER_ECO)) {
|
||||
throw new Exception('SACY_TRANSFORMER_ECO defined but not executable');
|
||||
}
|
||||
// Calling eco with the filename here. Using stdin wouldn't
|
||||
// cut it, as eco uses the filename to figure out the name of
|
||||
// the js function it outputs.
|
||||
$eco_root = $opts['eco-root'];
|
||||
|
||||
return sprintf('%s %s -p %s',
|
||||
SACY_TRANSFORMER_ECO,
|
||||
$eco_root ? sprintf('-i %s', escapeshellarg($eco_root)) : '',
|
||||
escapeshellarg($filename)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ProcessorSass extends ExternalProcessor
|
||||
{
|
||||
protected function getType()
|
||||
{
|
||||
return 'text/x-sass';
|
||||
}
|
||||
|
||||
protected function getCommandLine($filename, $opts = [])
|
||||
{
|
||||
if (!is_executable(SACY_TRANSFORMER_SASS)) {
|
||||
throw new Exception('SACY_TRANSFORMER_SASS defined but not executable');
|
||||
}
|
||||
$libpath = $opts['library_path'] ?: [dirname($filename)];
|
||||
$libpath[] = $_SERVER['DOCUMENT_ROOT'] ?: getcwd();
|
||||
|
||||
$path =
|
||||
implode(' ', array_map(function ($p) {
|
||||
return '-I '.escapeshellarg($p);
|
||||
}, array_unique($libpath)));
|
||||
|
||||
return sprintf('%s --cache-location=%s -s %s %s',
|
||||
SACY_TRANSFORMER_SASS,
|
||||
escapeshellarg(sys_get_temp_dir()),
|
||||
$this->getType() == 'text/x-scss' ? '--scss' : '',
|
||||
$path
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ProcessorScss extends ProcessorSass
|
||||
{
|
||||
protected function getType()
|
||||
{
|
||||
return 'text/x-scss';
|
||||
}
|
||||
}
|
||||
|
||||
class ProcessorLess extends ExternalProcessor
|
||||
{
|
||||
protected function getCommandLine($filename, $opts = [])
|
||||
{
|
||||
if (!is_executable(SACY_TRANSFORMER_LESS)) {
|
||||
throw new \Exception('SACY_TRANSFORMER_LESS defined but not executable');
|
||||
}
|
||||
|
||||
return sprintf(
|
||||
'%s -I%s -',
|
||||
SACY_TRANSFORMER_LESS,
|
||||
escapeshellarg(dirname($filename))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ProcessorJSX extends ExternalProcessor
|
||||
{
|
||||
protected function getCommandLine($filename, $opts = [])
|
||||
{
|
||||
if (!is_executable(SACY_TRANSFORMER_JSX)) {
|
||||
throw new Exception('SACY_TRANSFORMER_JSX defined but not executable');
|
||||
}
|
||||
|
||||
return SACY_TRANSFORMER_JSX;
|
||||
}
|
||||
}
|
||||
|
||||
class ProcessorFontIcons extends ExternalProcessor
|
||||
{
|
||||
protected function getCommandLine($filename, $opts = [])
|
||||
{
|
||||
return SACY_TRANSFORMER_FONTICONS." compile 'templates/icons/' -F -c {$filename}";
|
||||
}
|
||||
|
||||
public function transform($in, $filename, $opts = [])
|
||||
{
|
||||
$css = 'data/tmp/cache/icons.css';
|
||||
|
||||
if (@filemtime($filename) > @filemtime($css)) {
|
||||
parent::transform($in, $filename, $opts);
|
||||
}
|
||||
|
||||
return str_replace('./icons', '/data/tmp/cache/icons', file_get_contents($css));
|
||||
}
|
||||
}
|
||||
|
||||
if (defined('SACY_COMPRESSOR_UGLIFY')) {
|
||||
ExternalProcessorRegistry::registerCompressor('text/javascript', 'sacy\ProcessorUglify');
|
||||
}
|
||||
|
||||
if (defined('SACY_TRANSFORMER_COFFEE')) {
|
||||
ExternalProcessorRegistry::registerTransformer('text/coffeescript', 'sacy\ProcessorCoffee');
|
||||
}
|
||||
|
||||
if (defined('SACY_TRANSFORMER_ECO')) {
|
||||
ExternalProcessorRegistry::registerTransformer('text/x-eco', 'sacy\ProcessorEco');
|
||||
}
|
||||
|
||||
if (defined('SACY_TRANSFORMER_SASS')) {
|
||||
ExternalProcessorRegistry::registerTransformer('text/x-sass', 'sacy\ProcessorSass');
|
||||
ExternalProcessorRegistry::registerTransformer('text/x-scss', 'sacy\ProcessorScss');
|
||||
}
|
||||
|
||||
if (defined('SACY_TRANSFORMER_FONTICONS')) {
|
||||
ExternalProcessorRegistry::registerTransformer('image/svg+xml', 'sacy\ProcessorFontIcons');
|
||||
}
|
||||
|
||||
if (defined('SACY_TRANSFORMER_LESS')) {
|
||||
ExternalProcessorRegistry::registerTransformer('text/x-less', 'sacy\ProcessorLess');
|
||||
}
|
||||
|
||||
if (defined('SACY_TRANSFORMER_JSX')) {
|
||||
ExternalProcessorRegistry::registerTransformer('text/x-jsx', 'sacy\ProcessorJSX');
|
||||
}
|
||||
Reference in New Issue
Block a user