
================
csx.Declarations
================

Extends `dict` and `csx._Renderable` to represent a CSX declaration block.


Instantiation
=============

With a `str`::

    >>> from csx import Declarations

    >>> declarations = Declarations("""
    ...
    ...     /* text properties */
    ...
    ...     font: italic 12px "Scala Sans", Verdana, sans-serif;
    ...     line-height: 1.5;
    ...     margin: 1em;
    ...     z-index: 1;
    ...
    ... """)

With an iterable of `csx.Declaration` objects::

    >>> from csx import Declaration

    >>> from_set = Declarations({
    ...     Declaration('font: italic 12px "Scala Sans", Verdana, sans-serif'),
    ...     Declaration("line-height: 1.5"),
    ...     Declaration("margin: 1em"),
    ...     Declaration("z-index: 1"),
    ... })

With a `dict`::

    >>> from_dict = Declarations({
    ...     "font": 'italic 12px "Scala Sans", Verdana, sans-serif',
    ...     "line-height": "1.5",
    ...     "margin": "1em",
    ...     "z-index": "1",
    ... })

With an iterable of 2-tuples::

    >>> from_list = Declarations([
    ...     ("font", 'italic 12px "Scala Sans", Verdana, sans-serif'),
    ...     ("line-height", "1.5"),
    ...     ("margin", "1em"),
    ...     ("z-index", "1"),
    ... ])

With keyword arguments (underscores are converted to hyphens in keywords)::

    >>> from_keyword = Declarations(
    ...     font='italic 12px "Scala Sans", Verdana, sans-serif',
    ...     line_height="1.5",
    ...     margin="1em",
    ...     z_index="1",
    ... )

(all of the above create identical `Declarations` objects) ::

    >>> examples = [declarations, from_set, from_dict, from_list, from_keyword]

    >>> assert all(x == y for x in examples for y in examples)


Features
========

Unlike regular `dict` objects, `Declarations` is orderable. ::

    >>> from pprint import pprint

    >>> pprint(sorted([
    ...     Declarations("color: red"),
    ...     Declarations("background: yellow"),
    ...     Declarations("color: blue"),
    ...     Declarations("background: white"),
    ...     Declarations("color: red; background: white"),
    ...     Declarations("background: yellow; color: red"),
    ...     Declarations("color: blue; background: yellow"),
    ...     Declarations("background: white; color: blue"),
    ... ]))
    [Declarations('background: white'),
     Declarations('background: white; color: blue'),
     Declarations('background: white; color: red'),
     Declarations('background: yellow'),
     Declarations('background: yellow; color: blue'),
     Declarations('background: yellow; color: red'),
     Declarations('color: blue'),
     Declarations('color: red')]


Methods
=======

items()
-------

Behaves like `dict.items`, except that it returns a set of `Declaration`
objects rather than a `dict_items` view. Because `Declaration` objects are
basically 2-tuples, the result is essentially the same. ::

    >>> pprint(declarations.items())
    {Declaration('font: italic 12px "Scala Sans", Verdana, sans-serif'),
     Declaration('line-height: 1.5'),
     Declaration('margin: 1em'),
     Declaration('z-index: 1')}

    >>> pprint({x[:] for x in declarations.items()})
    {('font', 'italic 12px "Scala Sans", Verdana, sans-serif'),
     ('line-height', '1.5'),
     ('margin', '1em'),
     ('z-index', '1')}


render([style="pretty"], [level=0])
-----------------------------------

Returns a formatted representation of the declaration block. At least one
argument, `style`, must be supplied, which may be one of "bare", "compact" or
"pretty". ::

    >>> colors = Declarations("background: red; color: yellow")

    >>> print(colors.render("bare"))
    background:red;color:yellow

    >>> print(colors.render("compact"))
    background: red; color: yellow

    >>> print(colors.render("pretty"))
    background: red;
    color: yellow;

`level` (which defaults to 0) is the level of indentation of the output. ::

    >>> print(colors.render("pretty", level=2))
            background: red;
            color: yellow;

