/// <summary> /// Replace all rgb(#,#,#) and rgba(#,#,#,1) strings with their hex value, /// Replace all hsl(#,#,#) and hsla(#,#,#,1) strings with their hex value. /// </summary> private static void ConvertColors( ref string source ) { var colors = new ColorConversions(); char[] parens = { '(', ')' }; string[] nums; source = Regex.Replace( source, "rgba?\\(\\d{1,3},\\d{1,3},\\d{1,3}(,1)?\\)", m => { nums = m.Value.Split( parens )[ 1 ].Split( ',' ); try { byte[] rgb = { Byte.Parse( nums[ 0 ] ), Byte.Parse( nums[ 1 ] ), Byte.Parse( nums[ 2 ] ) }; return m.Value.Replace( m.Value, colors.ConvertRgbToHex( rgb ) ); } catch( Exception e ) { if( e is ArgumentNullException || e is FormatException || e is OverflowException ) { MessageBox.Show( "Failed to parse " + m.Value, "Parse Error" ); } else { throw; } } return m.Value; } ); // Have to '{0,1}' the '%' since they may have been removed in a previous step source = Regex.Replace( source, "hsla?\\(\\d{1,3},\\d{1,3}%?,\\d{1,3}%?(,1)?\\)", m => { nums = m.Value.Replace( "%", string.Empty ).Split( parens )[ 1 ].Split( ',' ); double h, s, l; try { h = Double.Parse( nums[ 0 ] ) / 360; s = Double.Parse( nums[ 1 ] ) / 100; l = Double.Parse( nums[ 2 ] ) / 100; return m.Value.Replace( m.Value, colors.ConvertHslToHex( h, s, l ) ); } catch( Exception ex ) { if( ex is ArgumentNullException || ex is FormatException || ex is OverflowException ) { MessageBox.Show( "Failed to parse " + m.Value, "Parse Error" ); } else { throw; } } return m.Value; } ); }
/// <summary> /// Cleans/compresses several aspects of CSS code. /// </summary> /// <remarks> /// This should be everything... /// </remarks> /// <param name="css">The string value of the file(s).</param> /// <returns>A minified version of the supplied CSS string.</returns> public static string MakeItUgly( string css ) { var colors = new ColorConversions(); // Clear the lists _urls.Clear(); _data.Clear(); _contents.Clear(); // Insert placeholders SwapForPlaceholders( ref css ); // Run through the rest of the minify methods InitialCleaning( ref css ); CleanSelectors( ref css ); CleanBraces( ref css ); CleanUnnecessary( ref css ); ConvertColors( ref css ); CompressHexValues( ref css ); css = colors.SwapOutNames( css ); FixIllFormedHsl( ref css ); // 'transparent' == rgba(0,0,0,0) == hsla(0,0%,0%,0) // Should be fine, if it supports Alpha should support the 'transparent' color literal // ...right? css = css.Replace( "rgba(0,0,0,0)", "transparent" ) .Replace( "hsla(0,0%,0%,0)", "transparent" ); // Replace placeholders ReplacePlaceholders( ref css ); // Return the string after trimming any leading or trailing spaces return css.Trim(); }
/// <summary> /// Match hex values that are 6 long, can ignore length 3 for now, and compress them down to 3 if possible, /// Grab all the hex strings and see if the literal color name is shorter than the hex value, if so, replace it. /// </summary> private static void CompressHexValues( ref string source ) { var colors = new ColorConversions(); string tmp = string.Empty; source = Regex.Replace( source, "#[0-9a-fA-F]{6}(?=,|;|\\}\\)\\s)", m => { tmp = colors.CompressHex( m.Value.Replace( "#", string.Empty ) ); return m.Value.Replace( m.Value, tmp ); } ); source = Regex.Replace( source, "#([0-9a-fA-F]{3}){1,2}(?=,|;|\\}\\)\\s)", m => { tmp = colors.SwapOutHex( m.Value ); return m.Value.Replace( m.Value, tmp ); } ); }