CSS compressor written in OCaml

Taddeus Kroes 591c9af716 Code cleanup преди 11 години
test dfa989a524 Added some test files for manual inspection преди 11 години
.gitignore cccf4c432e Added generated file to ignore file преди 11 години
Makefile 2e91dba8c7 Moved pre-built binary to separate server преди 11 години
README.md f69c40b65a Typo преди 11 години
color_names.ml bf099c1049 Bugfix in color conversion преди 11 години
duplicates.ml 591c9af716 Code cleanup преди 11 години
lexer.mll bc51af6350 Added support for exotic browser-specific syntax such as @-ms-viewport and filter(opacity=60) преди 11 години
main.ml 0f0ddfeda0 Forgot newline in usage message преди 11 години
parse.ml 70f032a31d Lexer now correctly tracks line numbers + some general cleanup преди 11 години
parser.mly bc51af6350 Added support for exotic browser-specific syntax such as @-ms-viewport and filter(opacity=60) преди 11 години
selector.ml 369ee206ec Bugfix in unused code преди 11 години
shorthand.ml 591c9af716 Code cleanup преди 11 години
simple.ml 591c9af716 Code cleanup преди 11 години
stringify.ml bc51af6350 Added support for exotic browser-specific syntax such as @-ms-viewport and filter(opacity=60) преди 11 години
types.ml bc51af6350 Added support for exotic browser-specific syntax such as @-ms-viewport and filter(opacity=60) преди 11 години
util.ml 591c9af716 Code cleanup преди 11 години

README.md

About

mincss is an extendible CSS minifier written in OCaml. It features a complete parser for the CSS3 language, along with type definitions that are consistent with the official CSS specification and a traversal utility function for use in transformation passes.

Installation

For now, there is no easy installation option for mincss (yet). An up-to-date 64-bit ELF binary is available for download here. You can also build the binary from source (see Building mincss below).

Features

Whitespace compression

a,                                  |  a,.myclass [class~="foo"]>p{color:#fff}
.myclass [class ~= "foo"] >  p {    |
    color: #fff;                    |
}                                   |

Compression of simple expressions

color: rgb(257, -2, 0);             |  color: red;
color: rgb(67%, 67.5%, 68%);        |  color: #abacad;
color: #aaffbb;                     |  color: #afb;
color: white;                       |  color: #fff;
font-weight: normal;                |  font-weight: 400;

Generation of shorthand properties

font-weight: normal;                |  font: normal 12px/15px sans-serif;
font-size: 12px;                    |
line-height: 15px;                  |
font-family: sans-serif;            |

Any existing shorthands are first unfolded into their non-shorthand counterparts, after which the last value is used for shorthand generation:

font: normal 12px/15px sans-serif;  |  font: bold 12px/15px sans-serif;
font-weight: bold;                  |

Pruning duplicate declarations

color: #000;                        |  color: #fff;
color: #fff;                        |

Note that !important annotations are correctly handled:

color: #eee !important;             |  color: #000 !important;
color: #000 !important;             |
color: #fff;                        |

Sorting declarations

The --sort command-line option sorts declarations alphabetically. This option is disabled by default since it does not affect file size.

Command-line interface

Output of mincss -h:

Usage: ./mincss [<options>] [<file> ...]

Generic options:
 -h, --help        Show this help message
 -v, --verbose     Verbose mode: show compression rate
 -o <file>         Output file (defaults to stdout)
 <file> ...        Input files (default is to read from stdin)

Optimization flags (if none are specified, all are enabled):
 -w, --whitespace  Eliminate unnecessary whitespaces (has the greatest effect, omit for pretty-printing)
 -c, --simple      Shorten colors and font weights
 -s, --shorthands  Generate shorthand properties
 -d, --duplicates  Prune duplicate properties (WARNING: may affect cross-browser hacks)
 -p, --pretty      Shorthand for -c -s -d
 -e, --echo        Just parse and pretty-print, no optimizations

Formatting options:
 --sort            Sort declarations in each selector group

Building mincss

Dependencies are OCaml 4.0 and menhir.

Bootstrapping on a Debian system can be done as follows:

$ sudo apt-get install ocaml opam git
$ opam init
$ opam switch 4.01.0
$ opam install menhir
$ git clone git@github.com:taddeus/mincss.git
$ cd mincss
$ make
$ ./mincss --help

TODO / bugs

  • border shorthand generation produces out-of-order results when direction-specific declarations follow a generic border declaration. This produces inequivalent CSS, and could be fixed by unfolding each generic border declaration into four direction-specific ones, and sybsequently generating the shortest possible representation of the resulting box model.