|
|
@@ -1,97 +1,81 @@
|
|
|
-mincss is an extendible CSS minifier written in OCaml. It contains a complete
|
|
|
-parser for the CSS3 language, along with consistent type definitions and a
|
|
|
-traversal utility function for use in transformation passes.
|
|
|
+About
|
|
|
+=====
|
|
|
|
|
|
-mincss is currently still in development, finished components are the parser,
|
|
|
-stringification (along with whitespace compression), and color compression.
|
|
|
-Rulset merging is partially documented below but currently unimplemented.
|
|
|
+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.
|
|
|
|
|
|
|
|
|
-Features
|
|
|
-========
|
|
|
+Optimizations
|
|
|
+=============
|
|
|
|
|
|
-- Whitespace compression
|
|
|
-- Color compression
|
|
|
-- Creation of shorthand properties (e.g. `font` and `background`)
|
|
|
-- Ruleset merging (see below)
|
|
|
-- Command-line interface and web interface
|
|
|
+Whitespace compression
|
|
|
+----------------------
|
|
|
|
|
|
-Ruleset merging
|
|
|
----------------
|
|
|
+ a, | a,.myclass [class~="foo"]>p{color:#fff}
|
|
|
+ .myclass [class ~= "foo"] > p { |
|
|
|
+ color: #fff; |
|
|
|
+ } |
|
|
|
|
|
|
-Apart from simply writing the CSS in a shorter format (i.e.
|
|
|
-whitespace/color/shorthand compression), mincss attempts to restructure rule
|
|
|
-sets such that the resulting stylesheet is the minimal representation of the
|
|
|
-input. For example:
|
|
|
+Compression of simple expressions
|
|
|
+---------------------------------
|
|
|
|
|
|
- a { color: red }
|
|
|
- p { color: red }
|
|
|
+ color: white; | color: #fff;
|
|
|
+ font-weight: normal; | font-weight: 400;
|
|
|
|
|
|
-can be written much shorter as:
|
|
|
+Generation of shorthand properties
|
|
|
+----------------------------------
|
|
|
|
|
|
- a, p { color: red }
|
|
|
+ font-weight: normal; | font: normal 12px/15px sans-serif;
|
|
|
+ font-size: 12px; |
|
|
|
+ line-height: 15px; |
|
|
|
+ font-family: sans-serif; |
|
|
|
|
|
|
-Merging selectors is something that is done by the programmer in most cases,
|
|
|
-but the example above may occur when multiple different CSS files are merged
|
|
|
-into one, or when a large CSS file is structured in such a way that the
|
|
|
-definitions of `a` and `p` are far apart. Another thing that may happen is that
|
|
|
-some framework file defines a default style for a selector, that is then
|
|
|
-overwritten in a custom stylesheet, for example:
|
|
|
+Any existing shorthands are first unfolded into their non-shorthand
|
|
|
+counterparts, after which the last value is used for shorthand generation:
|
|
|
|
|
|
- /* file: framework.css */
|
|
|
- a {
|
|
|
- border: 1px solid red;
|
|
|
- }
|
|
|
+ font: normal 12px/15px sans-serif; | font: bold 12px/15px sans-serif;
|
|
|
+ font-weight: bold; |
|
|
|
|
|
|
- ...
|
|
|
|
|
|
- /* file: my-special-page.css */
|
|
|
- a {
|
|
|
- border-color: blue;
|
|
|
- }
|
|
|
+Command-line interface
|
|
|
+======================
|
|
|
+Output of `mincss -h`:
|
|
|
|
|
|
-which can be merged into:
|
|
|
+ Usage: ./mincss [<options>] [<file> ...]
|
|
|
|
|
|
- a {
|
|
|
- border: 1px solid blue;
|
|
|
- }
|
|
|
+ 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
|
|
|
|
|
|
-Compression phases
|
|
|
-==================
|
|
|
-
|
|
|
-To achieve the features listed above, the input stylesheet is rewritten in a
|
|
|
-number of steps:
|
|
|
-
|
|
|
-1. Parse the input CSS, producing an Abstract Syntax Tree (AST) in accordance
|
|
|
- with the CSS syntax definition. This eliminates unnecessary whitespaces and
|
|
|
- catches syntax errors.
|
|
|
-2. Transform shorthand declarations into a separate declaration for each
|
|
|
- expression in the shorthand.
|
|
|
-3. Duplicate rulesets for each of its selectors, so that every ruleset has
|
|
|
- exactly one selector.
|
|
|
-4. Create a new declaration block for each property declaration on each
|
|
|
- selector, e.g. `a,p{color:red;border:blue}` becomes `a{color:red}
|
|
|
- a{border:blue} p{color:red} p{border:blue}`.
|
|
|
-5. Prune duplicate declarations (when the same property is overwritten for the
|
|
|
- same selector). Note: this may be disabled with `--no-prune` for stylesheets
|
|
|
- that contain duplication hacks.
|
|
|
-6. Combine selectors for identical blocks (as long as the correct order of
|
|
|
- declarations is preserved).
|
|
|
-7. Concatenate blocks for identical (combinations of) selectors.
|
|
|
-8. Optimize individual declaration blocks by generating shorthand declarations
|
|
|
- and simple compression on expressions (i.e. color compression, removal of
|
|
|
- unnecessary string quotes, etc.).
|
|
|
-9. Output the resulting AST with minimal whitespace.
|
|
|
+ Formatting options:
|
|
|
+ --sort Sort declarations in each selector group
|
|
|
|
|
|
|
|
|
Building mincss
|
|
|
===============
|
|
|
|
|
|
-TODO
|
|
|
-
|
|
|
+Dependencies are [OCaml](https://ocaml.org/docs/install.html) 4.0 and
|
|
|
+[menhir](http://cristal.inria.fr/~fpottier/menhir/).
|
|
|
|
|
|
-Compression scores
|
|
|
-==================
|
|
|
+Bootstrapping on a Debian system can be done as follows:
|
|
|
|
|
|
-TODO: compare to existing minifiers
|
|
|
+ $ 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
|