Minify a CSS string

@param  string $css Original CSS
@return string      Minified CSS
556677
protected function minify($css)
	{
		$css = trim($css, " \n\t;");
		$css = preg_replace('(\\s*([,:;])\\s*)', '$1', $css);
		$css = preg_replace_callback(
			'((?<=[\\s:])#[0-9a-f]{3,6})i',
			function ($m)
			{
				return strtolower($m[0]);
			},
			$css
		);
		$css = preg_replace('((?<=[\\s:])#([0-9a-f])\\1([0-9a-f])\\2([0-9a-f])\\3)', '#$1$2$3', $css);
		$css = preg_replace('((?<=[\\s:])#f00\\b)', 'red', $css);
		$css = preg_replace('((?<=[\\s:])0px\\b)', '0', $css);

		return $css;
	}
1100646
protected function _process($css)
    {
        $css = str_replace("\r\n", "\n", $css);
        
        // preserve empty comment after '>'
        // http://www.webdevout.net/css-hacks#in_css-selectors
        $css = preg_replace('@>/\\*\\s*\\*/@', '>/*keep*/', $css);
        
        // preserve empty comment between property and value
        // http://css-discuss.incutio.com/?page=BoxModelHack
        $css = preg_replace('@/\\*\\s*\\*/\\s*:@', '/*keep*/:', $css);
        $css = preg_replace('@:\\s*/\\*\\s*\\*/@', ':/*keep*/', $css);
        
        // apply callback to all valid comments (and strip out surrounding ws
        $css = preg_replace_callback('@\\s*/\\*([\\s\\S]*?)\\*/\\s*@'
            ,array($this, '_commentCB'), $css);

        // remove ws around { } and last semicolon in declaration block
        $css = preg_replace('/\\s*{\\s*/', '{', $css);
        $css = preg_replace('/;?\\s*}\\s*/', '}', $css);
        
        // remove ws surrounding semicolons
        $css = preg_replace('/\\s*;\\s*/', ';', $css);
        
        // remove ws around urls
        $css = preg_replace('/
                url\\(      # url(
                \\s*
                ([^\\)]+?)  # 1 = the URL (really just a bunch of non right parenthesis)
                \\s*
                \\)         # )
            /x', 'url($1)', $css);
        
        // remove ws between rules and colons
        $css = preg_replace('/
                \\s*
                ([{;])              # 1 = beginning of block or rule separator 
                \\s*
                ([\\*_]?[\\w\\-]+)  # 2 = property (and maybe IE filter)
                \\s*
                :
                \\s*
                (\\b|[#\'"])        # 3 = first character of a value
            /x', '$1$2:$3', $css);
        
        // remove ws in selectors
        $css = preg_replace_callback('/
                (?:              # non-capture
                    \\s*
                    [^~>+,\\s]+  # selector part
                    \\s*
                    [,>+~]       # combinators
                )+
                \\s*
                [^~>+,\\s]+      # selector part
                {                # open declaration block
            /x'
            ,array($this, '_selectorsCB'), $css);
        
        // minimize hex colors
        $css = preg_replace('/([^=])#([a-f\\d])\\2([a-f\\d])\\3([a-f\\d])\\4([\\s;\\}])/i'
            , '$1#$2$3$4$5', $css);
        
        // remove spaces between font families
        $css = preg_replace_callback('/font-family:([^;}]+)([;}])/'
            ,array($this, '_fontFamilyCB'), $css);
        
        $css = preg_replace('/@import\\s+url/', '@import url', $css);
        
        // replace any ws involving newlines with a single newline
        $css = preg_replace('/[ \\t]*\\n+\\s*/', "\n", $css);
        
        // separate common descendent selectors w/ newlines (to limit line lengths)
        $css = preg_replace('/([\\w#\\.\\*]+)\\s+([\\w#\\.\\*]+){/', "$1\n$2{", $css);
        
        // Use newline after 1st numeric value (to limit line lengths).
        $css = preg_replace('/
            ((?:padding|margin|border|outline):\\d+(?:px|em)?) # 1 = prop : 1st numeric value
            \\s+
            /x'
            ,"$1\n", $css);
        
        // prevent triggering IE6 bug: http://www.crankygeek.com/ie6pebug/
        $css = preg_replace('/:first-l(etter|ine)\\{/', ':first-l$1 {', $css);
            
        return trim($css);
    }
772060
private static function fixCursorProperties($css) {
		$css = preg_replace(
			self::$patterns['cursor_east'],
			'$1' . self::$patterns['tmpToken'],
			$css
		);
		$css = preg_replace(self::$patterns['cursor_west'], '$1e-resize', $css);
		$css = str_replace(self::$patterns['tmpToken'], 'w-resize', $css);

		return $css;
	}
1373512
public static function compress($js)
    {
        $js = (string) $js;
        try {
            $js_minifier = new static($js);
            $minified_js = $js_minifier->min();
            return $minified_js;
        } catch (\Exception $exception) {
            return $js;
        }
    }
135735
public function minifyCSS() {
      $css_dir = './css';
      if (is_dir($css_dir)) {
         foreach (glob("$css_dir/*.css") as $css_file) {
            if (!$this->endsWith($css_file, 'min.css')) {
               $this->taskMinify($css_file)
                  ->to(str_replace('.css', '.min.css', $css_file))
                  ->type('css')
                  ->run();
            }
         }
      }
      return $this;
   }
708403
public function css($string)
    {
        if (!$string) {
            return $string;
        }

        $string = $this->toUtf8($string);
        if ($string === '' || ctype_digit($string)) {
            return $string;
        }

        $result = preg_replace_callback('/[^a-z0-9]/iSu', $this->cssMatcher, $string);
        return $this->fromUtf8($result);
    }
651851
function make_styles_string($styles) {
        if (empty($styles)) {
            return null;
        }

        $string = '';
        foreach($styles as $property => $value) {
            $string .= $property . ':' . $value . ';';
        }
        return $string;
    }
599557
public function convertToColor($css, &$res)
    {
        // prepare the value
        $css = trim($css);
        $res = true;

        // if transparent => return null
        if (strtolower($css) === 'transparent') {
            return array(null, null, null);
        }

        // HTML color
        if (isset($this->htmlColor[strtolower($css)])) {
            $css = $this->htmlColor[strtolower($css)];
            $r = floatVal(hexdec(substr($css, 0, 2)));
            $g = floatVal(hexdec(substr($css, 2, 2)));
            $b = floatVal(hexdec(substr($css, 4, 2)));
            return array($r, $g, $b);
        }

        // like #FFFFFF
        if (preg_match('/^#[0-9A-Fa-f]{6}$/isU', $css)) {
            $r = floatVal(hexdec(substr($css, 1, 2)));
            $g = floatVal(hexdec(substr($css, 3, 2)));
            $b = floatVal(hexdec(substr($css, 5, 2)));
            return array($r, $g, $b);
        }

        // like #FFF
        if (preg_match('/^#[0-9A-F]{3}$/isU', $css)) {
            $r = floatVal(hexdec(substr($css, 1, 1).substr($css, 1, 1)));
            $g = floatVal(hexdec(substr($css, 2, 1).substr($css, 2, 1)));
            $b = floatVal(hexdec(substr($css, 3, 1).substr($css, 3, 1)));
            return array($r, $g, $b);
        }

        // like rgb(100, 100, 100)
        $sub = '[\s]*([0-9%\.]+)[\s]*';
        if (preg_match('/rgb\('.$sub.','.$sub.','.$sub.'\)/isU', $css, $match)) {
            $r = $this->convertSubColor($match[1]);
            $g = $this->convertSubColor($match[2]);
            $b = $this->convertSubColor($match[3]);
            return array($r * 255., $g * 255., $b * 255.);
        }

        // like cmyk(100, 100, 100, 100)
        $sub = '[\s]*([0-9%\.]+)[\s]*';
        if (preg_match('/cmyk\('.$sub.','.$sub.','.$sub.','.$sub.'\)/isU', $css, $match)) {
            $c = $this->convertSubColor($match[1]);
            $m = $this->convertSubColor($match[2]);
            $y = $this->convertSubColor($match[3]);
            $k = $this->convertSubColor($match[4]);
            return array($c * 100., $m * 100., $y * 100., $k * 100.);
        }

        $res = false;
        return array(0., 0., 0.);
    }
475804
protected function process($css)
        {
            $css = str_replace("\r\n", "\n", $css);

            // preserve empty comment after '>'
            // http://www.webdevout.net/css-hacks#in_css-selectors
            $css = preg_replace('@>/\\*\\s*\\*/@', '>/*keep*/', $css);

            // preserve empty comment between property and value
            // http://css-discuss.incutio.com/?page=BoxModelHack
            $css = preg_replace('@/\\*\\s*\\*/\\s*:@', '/*keep*/:', $css);
            $css = preg_replace('@:\\s*/\\*\\s*\\*/@', ':/*keep*/', $css);

            // apply callback to all valid comments (and strip out surrounding ws
            $css = preg_replace_callback(
                '@\\s*/\\*([\\s\\S]*?)\\*/\\s*@',
                array(
                    $this,
                    '_commentCB'
                ),
                $css
            );

            // remove ws around { } and last semicolon in declaration block
            $css = preg_replace('/\\s*{\\s*/', '{', $css);
            $css = preg_replace('/;?\\s*}\\s*/', '}', $css);

            // remove ws surrounding semicolons
            $css = preg_replace('/\\s*;\\s*/', ';', $css);

            // remove ws around urls
            $css = preg_replace('/
                    url\\(      # url(
                    \\s*
                    ([^\\)]+?)  # 1 = the URL (really just a bunch of non right parenthesis)
                    \\s*
                    \\)         # )
                /x',
                'url($1)',
                $css
            );

            // remove ws between rules and colons
            $css = preg_replace('/
                    \\s*
                    ([{;])              # 1 = beginning of block or rule separator
                    \\s*
                    ([\\*_]?[\\w\\-]+)  # 2 = property (and maybe IE filter)
                    \\s*
                    :
                    \\s*
                    (\\b|[#\'"])        # 3 = first character of a value
                /x',
                '$1$2:$3',
                $css
            );

            // remove ws in selectors
            $css = preg_replace_callback('/
                    (?:              # non-capture
                        \\s*
                        [^~>+,\\s]+  # selector part
                        \\s*
                        [,>+~]       # combinators
                    )+
                    \\s*
                    [^~>+,\\s]+      # selector part
                    {                # open declaration block
                /x',
                array(
                    $this,
                    '_selectorsCB'
                ),
                $css
            );

            // minimize hex colors
            $css = preg_replace('/([^=])#([a-f\\d])\\2([a-f\\d])\\3([a-f\\d])\\4([\\s;\\}])/i', '$1#$2$3$4$5', $css);

            // remove spaces between font families
            $css = preg_replace_callback('/font-family:([^;}]+)([;}])/', array($this, '_fontFamilyCB'), $css);

            $css = preg_replace('/@import\\s+url/', '@import url', $css);

            // replace any ws involving newlines with a single newline
            $css = preg_replace('/[ \\t]*\\n+\\s*/', "\n", $css);

            // separate common descendent selectors w/ newlines (to limit line lengths)
            $css = preg_replace('/([\\w#\\.\\*]+)\\s+([\\w#\\.\\*]+){/', "$1\n$2{", $css);

            // Use newline after 1st numeric value (to limit line lengths).
            $css = preg_replace('/
                ((?:padding|margin|border|outline):\\d+(?:px|em)?) # 1 = prop : 1st numeric value
                \\s+
                /x',
                "$1\n",
                $css
            );

            // prevent triggering IE6 bug: http://www.crankygeek.com/ie6pebug/
            $css = preg_replace('/:first-l(etter|ine)\\{/', ':first-l$1 {', $css);

            return trim($css);
        }
303828
public function convertBackgroundColor($css)
    {
        $res = null;
        if ($css === 'transparent') {
            return null;
        }

        return $this->convertToColor($css, $res);
    }
8569
protected function maybeCompressCssCode($css)
    {
        if (($benchmark = !empty($this->options['benchmark']) && $this->options['benchmark'] === 'details')) {
            $time = microtime(true);
        }
        $css = (string) $css; // Force string value.

        if (isset($this->options['compress_css_code'])) {
            if (!$this->options['compress_css_code']) {
                $disabled = true; // Disabled flag.
            }
        }
        if (!$css || !empty($disabled)) {
            goto finale; // Nothing to do.
        }
        if (strlen($css) > 1000000) {
            // Exclude VERY large files. Too time-consuming.
            // Should really be compressed ahead-of-time anyway.
            goto finale; // Don't compress HUGE files.
        }
        try { // Catch CSS compression-related exceptions.
            if (!($compressed_css = \WebSharks\CssMinifier\Core::compress($css))) {
                // `E_USER_NOTICE` to avoid a show-stopping problem.
                trigger_error('CSS compression failure.', E_USER_NOTICE);
            } else {
                $css = $this->stripUtf8Bom($compressed_css);
            } // Use compressed CSS file.
        } catch (\Exception $exception) {
            trigger_error($exception->getMessage(), E_USER_NOTICE);
        }
        finale: // Target point; finale/return value.

        if ($css) {
            $css = trim($css);
        }
        if ($benchmark && !empty($time) && $css && empty($disabled)) {
            $this->benchmark->addTime(
                __FUNCTION__,
                $time, // Caller, start time, task performed.
                sprintf('compressing CSS w/ checksum: `%1$s`', md5($css))
            );
        }
        return $css;
    }
957540
private function optimizeCssCode($code)
	{
		if (YII_DEBUG)
			return $code;

		require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'CssMin.php';
		return CssMin::minify($code);
	}
246555
public static function minify($source, array $filters = null, array $plugins = null)
		{
		self::$errors = array();
		$minifier = new CssMinifier($source, $filters, $plugins);
		return $minifier->getMinified();
		}
120626
protected function stripExistingCssCharsets($css)
    {
        if (!($css = (string) $css)) {
            return $css; // Nothing to do.
        }
        $css        = preg_replace('/@(?:\-(?:'.$this->regex_vendor_css_prefixes.')\-)?charset(?:\s+[^;]*?)?;/ui', '', $css);
        return $css = $css ? trim($css) : $css;
    }
1255918
function minifyCss() {
  var stream = gulp.src([compiled.css + '/**/*', '!' + compiled.css + '/styleguide*'])
    .pipe(plugins.minifyCss())
    .pipe(plugins.rename({ suffix: '.min' }))
    .pipe(gulp.dest(dist.css));
  return stream;
}
1318411
public static function css_files(array $files) {
        if (empty($files)) {
            return '';
        }

        $compressed = array();
        foreach ($files as $file) {
            $content = file_get_contents($file);
            if ($content === false) {
                $compressed[] = "\n\n/* Cannot read CSS file ".basename(dirname(dirname($file))).'/'.basename(dirname($file)).'/'.basename($file)."*/\n\n";
                continue;
            }
            $compressed[] = self::css($content);
        }

        return implode("\n", $compressed);
    }
1330172
public static function baseCss($css = null)
    {
        if (!is_null($css)) {
            return static::$baseCss = $css;
        }

        $skin = config('admin.skin', 'skin-blue-light');

        array_unshift(static::$baseCss, "vendor/laravel-admin/AdminLTE/dist/css/skins/{$skin}.min.css");

        return static::$baseCss;
    }