Skip to content

Instantly share code, notes, and snippets.

@jehoshua02
Last active December 10, 2015 12:48
Show Gist options
  • Select an option

  • Save jehoshua02/4436314 to your computer and use it in GitHub Desktop.

Select an option

Save jehoshua02/4436314 to your computer and use it in GitHub Desktop.
<?php
require 'Sass.php';
// files to convert
$files = array(
'global',
);
// set paths
$scssPath = __DIR__ . '/scss';
$cssPath = __DIR__ . '/public/css';
// expand files to input output pairs
foreach ($files as &$file) {
$file = sprintf('%2$s/%1$s.scss:%3$s/%1$s.css', $file, $scssPath, $cssPath);
}
unset($file);
// compile
$sass = new Sass();
$sass->setScss()
->setStyle('compressed')
->setWatch()
->setCompass()
->setNoCache()
->compile($files);
<?php
class Sass
{
/**
* Options for sass command
*
* @var array
*/
protected $options = array();
/**
* Holds backup of options. Used by getHelp and getVersion
*
* @var array
*/
protected $optionsBackup = array();
/**
* Command line options
*
* @var array
*/
protected $commandOptions = array(
'stdin' => '--stdin',
'trace' => '--trace',
'unixLines' => '--unix-newlines',
'scss' => '--scss',
'watch' => '--watch',
'update' => '--update',
'stopOnError' => '--stop-on-error',
'poll' => '--poll',
'force' => '--force',
'check' => '--check',
'style' => '--style %s',
'precision' => '--precision %s',
'quiet' => '--quiet',
'compass' => '--compass',
'debugInfo' => '--debug-info',
'lineComments' => '--line-comments',
'interactive' => '--interactive',
'loadPath' => '--load-path %s',
'require' => '--require %s',
'cacheLocation' => '--cache-location %s',
'noCache' => '--no-cache',
'encoding' => '-E %s',
'help' => '--help',
'version' => '--version',
);
const STYLE_DEFAULT = 'nested';
const PRECISION_DEFAULT = 3;
const CACHE_LOCATION_DEFAULT = '.sass-cache';
/**
* Converts SCSS or Sass files to CSS
*
* @param string $input
* @param string $output
*
* @return string
*/
public function compile($files)
{
$command = $files;
array_unshift($command, $this->getCommand());
return $this->execute(implode(' ', $command));
}
/**
* Read input from standard input instead of an input file
*
* @param boolean $value
*/
public function setStdin($value = true)
{
return $this->setOption('stdin', $value);
}
/**
* Show a full traceback on error
*
* @param boolean $value
*/
public function setTrace($value = true)
{
return $this->setOption('trace', $value);
}
/**
* Use Unix-style newlines in written files
*
* @param boolean $value
*/
public function setUnixLines($value = true)
{
return $this->setOption('unixLines', $value);
}
/**
* Use the CSS-superset SCSS syntax
*
* @param boolean $value
*/
public function setScss($value = true)
{
return $this->setOption('scss', $value);
}
/**
* Watch files or directories for changes
*
* @param boolean $value
*/
public function setWatch($value = true)
{
return $this->setOption('watch', $value);
}
/**
* Compile files or directories to CSS
*
* @param boolean $value
*/
public function setUpdate($value = true)
{
return $this->setOption('update', $value);
}
/**
* If a file fails to compile, exit immediately. Only meaningful for
* --watch and --update
*
* @param boolean $value
*/
public function setStopOnError($value = true)
{
return $this->setOption('stopOnError', $value);
}
/**
* Check for file changes manually, rather than relying on the OS. Only
* meaningful for --watch
*
* @param boolean $value
*/
public function setPoll($value = true)
{
return $this->setOption('poll', $value);
}
/**
* Recompile all Sass files, even if the CSS file is newer. Only meaningful
* for --update
*
* @param boolean $value
*/
public function setForce($value = true)
{
return $this->setOption('force', $value);
}
/**
* Just check syntax, don't evaluate
*
* @param boolean $value
*/
public function setCheck($value = true)
{
return $this->setOption('check', $value);
}
/**
* Output style
*
* @param string $value Can be nested (default), compact, compressed, or expanded
*/
public function setStyle($value)
{
return $this->setOption('style', $value);
}
/**
* How many digits of precision to use when outputting decimal numbers. Defaults to 3
*
* @param int $value
*/
public function setPrecision($value)
{
return $this->setOption('precision', $value);
}
/**
* Silence warnings and status messages during compilation
*
* @param boolean $value
*/
public function setQuiet($value = true)
{
return $this->setOption('quiet', $value);
}
/**
* Make Compass imports available and load project configuration
*
* @param boolean $value
*/
public function setCompass($value = true)
{
return $this->setOption('compass', $value);
}
/**
* Emit extra information in the generated CSS that can be used by the FireSass Firebug plugin
*
* @param boolean $value
*/
public function setDebugInfo($value = true)
{
return $this->setOption('debugInfo', $value);
}
/**
* Emit comments in the generated CSS indicating the corresponding source line
*
* @param boolean $value
*/
public function setLineComments($value = true)
{
return $this->setOption('lineComments', $value);
}
/**
* Run an interactive SassScript shell
*
* @param boolean $value
*/
public function setInteractive($value = true)
{
return $this->setOption('interactive', $value);
}
/**
* Add a sass import path
*
* @param string $value
*/
public function addLoadPath($value)
{
return $this->setOption('loadPath', $value);
}
/**
* Require a Ruby library before running Sass
*
* @param string $value
*/
public function addRequire($value)
{
return $this->setOption('require', $value);
}
/**
* The path to put cached Sass files. Defaults to .sass-cache
*
* @param string $value
*/
public function setCacheLocation($value)
{
return $this->setOption('cacheLocation', $value);
}
/**
* Don't cache to sassc files
*
* @param boolean $value
*/
public function setNoCache($value = true)
{
return $this->setOption('noCache', $value);
}
/**
* Specify the default encoding for Sass files
*
* @param string $value
*/
public function setEncoding($value)
{
return $this->setOption('noCache', $value);
}
/**
* Returns help message
*
* @return string
*/
public function getHelp()
{
$this->backupOptions();
$this->clearOptions();
$this->setOption('help', true);
$output = $this->execute();
$this->restoreOptions();
return $output;
}
/**
* Returns version
*
* @return string
*/
public function getVersion()
{
$this->backupOptions();
$this->clearOptions();
$this->setOption('version', true);
$output = $this->execute();
$this->restoreOptions();
return $output;
}
/**
* Sets an option
*
* @param string $option
* @param mixed $value
*/
protected function setOption($option, $value)
{
switch ($option) {
case 'style':
if ($value == self::STYLE_DEFAULT) {
unset($this->options[$option]);
} else {
$this->options[$option] = $value;
}
break;
case 'precision':
if ($value == self::PRECISION_DEFAULT) {
unset($this->options[$option]);
} else {
$this->options[$option] = $value;
}
break;
case 'loadPath':
case 'require':
if (!array_key_exists($option, $this->options)) {
$this->options[$option] = array();
}
array_push($this->options[$option], $value);
break;
case 'encoding':
$this->options[$option] = $value;
break;
case 'cacheLocation':
if ($value == self::CACHE_LOCATION_DEFAULT) {
unset($this->options[$option]);
} else {
$this->options[$option] = $value;
}
break;
default:
if ($value === true) {
$this->options[$option] = true;
} else {
unset($this->options[$option]);
}
}
return $this;
}
/**
* Copies options for backup
*/
protected function backupOptions()
{
$this->optionsBackup = $this->options;
}
/**
* Clears options
*/
protected function clearOptions()
{
$this->options = array();
}
/**
* Restores options from backup
*/
protected function restoreOptions()
{
$this->options = $this->optionsBackup;
$this->optionsBackup = array();
}
/**
* Returns the command string for sass
*
* @return string
*/
protected function getCommand()
{
$command = array('sass');
foreach ($this->options as $option => $value) {
array_push($command, $this->getCommandOption($option, $value));
}
return implode(' ', $command);
}
/**
* Returns a command option
*
* @param string $option
* @param mixed $value
*
* @return string
*/
protected function getCommandOption($option, $value)
{
switch ($option) {
case 'style':
case 'precision':
case 'cache-location':
case 'encoding':
return sprintf($this->commandOptions[$option], $value);
case 'loadPath':
case 'require':
$commandOptions = array();
foreach ($value as $v) {
$commandOptions[] = sprintf($this->commandOptions[$option], $v);
}
return implode(' ', $commandOptions);
default:
if ($value === true) {
return $this->commandOptions[$option];
}
}
}
/**
* Executes a command on system. Returns system output
*
* @param string $command
*
* @return string
*/
protected function execute($command = null)
{
if ($command === null) {
$command = $this->getCommand();
}
exec($command, $output);
return implode("\n", $output);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment