Skip to content

Instantly share code, notes, and snippets.

@sgrossberndt
Last active August 29, 2015 14:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sgrossberndt/8a9ed9c73d0c450b21df to your computer and use it in GitHub Desktop.
Save sgrossberndt/8a9ed9c73d0c450b21df to your computer and use it in GitHub Desktop.
<?php
define('CR', chr(13));
class ResourceCompressor {
/**
* Callback function for preg_replace
*
* @see compressCssFile
* @param array $matches
* @return string the compressed string
*/
static public function compressCssPregCallback($matches) {
if ($matches[1]) {
// Group 1: Double quoted string.
return $matches[1];
} elseif ($matches[2]) {
// Group 2: Single quoted string.
return $matches[2];
} elseif ($matches[3]) {
// Group 3: Regular non-MacIE5-hack comment.
return '
';
} elseif ($matches[4]) {
// Group 4: MacIE5-hack-type-1 comment.
return '
/*\\T1*/
';
} elseif ($matches[5]) {
// Group 5,6,7: MacIE5-hack-type-2 comment
$matches[6] = preg_replace('/\\s++([+>{};,)])/S', '$1', $matches[6]);
// Clean pre-punctuation.
$matches[6] = preg_replace('/([+>{}:;,(])\\s++/S', '$1', $matches[6]);
// Clean post-punctuation.
$matches[6] = preg_replace('/;?\\}/S', '}
', $matches[6]);
// Add a touch of formatting.
return '
/*T2\\*/' . $matches[6] . '
/*T2E*/
';
} elseif ($matches[8]) {
// Group 8: calc function (see http://www.w3.org/TR/2006/WD-css3-values-20060919/#calc)
return 'calc' . $matches[8];
} elseif (isset($matches[9])) {
// Group 9: Non-string, non-comment. Safe to clean whitespace here.
$matches[9] = preg_replace('/^\\s++/', '', $matches[9]);
// Strip all leading whitespace.
$matches[9] = preg_replace('/\\s++$/', '', $matches[9]);
// Strip all trailing whitespace.
$matches[9] = preg_replace('/\\s{2,}+/', ' ', $matches[9]);
// Consolidate multiple whitespace.
$matches[9] = preg_replace('/\\s++([+>{};,)])/S', '$1', $matches[9]);
// Clean pre-punctuation.
$matches[9] = preg_replace('/([+>{}:;,(])\\s++/S', '$1', $matches[9]);
// Clean post-punctuation.
$matches[9] = preg_replace('/;?\\}/S', '}
', $matches[9]);
// Add a touch of formatting.
return $matches[9];
}
return $matches[0] . '
/* ERROR! Unexpected _proccess_css_minify() parameter */
';
}
/**
* Compress a CSS string by removing comments and whitespace characters
*
* @param string $contents
* @return string
*/
static public function compressCssString($contents) {
// Perform some safe CSS optimizations.
$contents = str_replace(CR, '', $contents);
// Strip any and all carriage returns.
// Match and process strings, comments and everything else, one chunk at a time.
// To understand this regex, read: "Mastering Regular Expressions 3rd Edition" chapter 6.
$contents = preg_replace_callback('%
# One-regex-to-rule-them-all! - version: 20100220_0100
# Group 1: Match a double quoted string.
("[^"\\\\]*+(?:\\\\.[^"\\\\]*+)*+") | # or...
# Group 2: Match a single quoted string.
(\'[^\'\\\\]*+(?:\\\\.[^\'\\\\]*+)*+\') | # or...
# Group 3: Match a regular non-MacIE5-hack comment.
(/\\*[^\\\\*]*+\\*++(?:[^\\\\*/][^\\\\*]*+\\*++)*+/) | # or...
# Group 4: Match a MacIE5-type1 comment.
(/\\*(?:[^*\\\\]*+\\**+(?!/))*+\\\\[^*]*+\\*++(?:[^*/][^*]*+\\*++)*+/(?<!\\\\\\*/)) | # or...
# Group 5: Match a MacIE5-type2 comment.
(/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/(?<=\\\\\\*/)) # folllowed by...
# Group 6: Match everything up to final closing regular comment
([^/]*+(?:(?!\\*)/[^/]*+)*?)
# Group 7: Match final closing regular comment
(/\\*[^/]++(?:(?<!\\*)/(?!\\*)[^/]*+)*+/(?<=(?<!\\\\)\\*/)) | # or...
# Group 8: Match a calc function (see http://www.w3.org/TR/2006/WD-css3-values-20060919/#calc)
(?:calc(\\((?:(?:[^\\(\\)]+)|(?8))*+\\))) | # or...
# Group 9: Match regular non-string, non-comment text.
((?:[^"\'/](?!calc))*+(?:(?!/\\*)/(?:[^"\'/](?!calc))*+)*+)
%Ssx', array('self', 'compressCssPregCallback'), $contents);
// Do it!
$contents = preg_replace('/^\\s++/', '', $contents);
// Strip leading whitespace.
$contents = preg_replace('/[ \\t]*+\\n\\s*+/S', '
', $contents);
// Consolidate multi-lines space.
$contents = preg_replace('/(?<!\\s)\\s*+$/S', '
', $contents);
return $contents;
}
}
ResourceCompressor::compressCssString(file_get_contents('segfault.css'));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment