2.0 (2015-01-17)
----------------

No changes.


2.0rc3 (2015-01-13)
-------------------

- webhelpers.html.tags

  * Further changes to ``select``, ``Options``, ``Option`` and ``OptGroup``:

    + The ``options`` argument no longer accepts sequences representing
      value-label pairs or option groups. Instead you must build up an
      ``Options`` instance and pass it. You can still pass a simple list
      of strings though.
    + The ``Options``, ``Option``, and ``OptGroup`` clsses have incompatible
      changes.
    + Move the ``selected_values`` argument from the ``Options`` constructor
      to the ``Options.render`` method. Calling ``str(options)`` now renders all
      the options unselected. To render the options with some selected you
      must call the ``render`` method (or let ``select`` call it for you).
    + The 'Option.selected' attribute is deleted.
    + ``Option`` and ``OptGroup`` no longer generate their own HTML.
    + The 'SelectedValues' class is deleted.


2.0rc2 (2014-11-11)
-------------------

- Several unit tests and bugfixes contributed by Jeff Dairiki.

- webhelpers2.containers

  * [bug][py3k] Fix ``ordered_items`` when ``other_keys`` is set.

- webhelpers2.html.builder

  * Add "checked" and "selected" to list of boolean attributes.
  * [bug] Fix "unknown keyword args" reporting in ``HTML()``.

- webhelpers2.html.tags

  * Overhaul ``select``, ``Options``, ``Option``, and ``OptGroup``:

    + Users should test their calls to verify no incompatibilities have crept
      in , especially if using unusual argument types or edge cases.
    + The main helper is now ``Options``; ``select`` is now a wrapper around it.
    + The classes are now fully autonomous and render themselves as strings.
      (Reverted in 2.0rc3.)
    + When options are rendered, the 'value' attribute is suppressed if it's
      identical to the label or None.
    + ``SelectedValues`` is a new support class used to convert the
      ``selected_values`` arguments. (Reverted in 2.0rc3.)

  * [bug] Fix OptGroup.__repr__ to list its arguments in the correct order

- webhelpers2.html.tools

  * [bug] Properly escape the string passed to ``js_obfuscate``.

- webhelpers2.misc

  * [feature] Reinstate formatted exceptions with ``StudlyException``
    class. (Replaces 'DeclarativeException' which was deleted in 2.0b1.)
  * [bug] format_exception() did not work if called with ``exc=None`` (due
    to missing ``import sys``.)

- webhelpers2.number

  * [bug] The format size helpers now format negative numbers correctly.
    Previously they passed the number unchanged and appended the unit
    suffix, which changed the quantity.
  * [bug] median() was not computing the median correctly for
    even-length sequences

- webhelpers2.text

  * [feature] New helper ``wrap_long_lines()``.
  * [bug] excerpt() now works correctly when ``text`` is a ``literal``.
  * [bug] wrap_paragraphs() now works when ``width`` is a
    ``textwrap.TextWrapper`` instance.

2.0rc1 (2014-09-22)
-------------------

- webhelpers.html._literal

  * Implementation of 'literal' moved to this private module.
  * New method .lit_join() works like .join() but does not escape the parts.

- webhelpers.html.builder:

  * 'HTMLBuilder.\_\_call\_\_()' accepts keyword args 'nl' and 'lit'. If 'nl'
    is true, add a newline after each element. If 'lit' is true, don't escape
    the elements when joining them.
  * 'HTMLBuilder.literal()' is the 'literal' class constructor. As a
    consequence it no longer accepts multiple positional args.
    Use '.\_\_call\_\_()' with 'lit=True' as an alternative.
  * '.comment()' adds a space before and after the content.
  * 'HTMLBuilder.void_tags' is a set of tag names to render in the self-closing
    style because they can never have content. It replaces the 'empty_tags'
    global. Add HTML 5 tags to list: "command", "keygen", "source".
  * 'HTMLBuilder.compose_attrs' is a dict of attribute names to string
    separators. If the tag method is called with any of these attributes and
    their value is a list or tuple, join the elements into a string using this
    separator.  The separators should be literals.
  * 'HTMLBuilder.boolean_attrs' is a set of attribute names which are
    converted to HTML boolean syntax if passed to the tag method. The current
    set is a conservative few commonly used in tags: "defer", "disabled", 
    "multiple", "readonly". You can pass additional ones for a specific tag
    as the "\_bool" argument to ``HTML.tag()``.
  * There doesn't seem to be an authoritative list of all boolean attributes;
    here are some lists on the web:
    http://stackoverflow.com/questions/706384/boolean-html-attributes
    https://github.com/kangax/html-minifier/issues/63
    We're evaluating whether to include all these. We're also evaluating
    whether it's better to convert them globally in any tag they appear in,
    or to convert some of them on a tag-by-tag basis. As far as we can tell,
    any attribute that's boolean in one case is boolean everywhere; we haven't
    seen any attribute that's boolean in one tag but non-boolean in another
    tag.
  * 'HTMLBuilder' has several literal constants as class attributes: EMPTY,
    SPACE, TAB2, TAB4, NL, BR, NL2, BR2.
    

  * Bugfixes:
  
    + Convert None to "" when passed to constructor.
    + Pass attribute when raising AttributeError.
    + ``re.sub`` overescapes in Python 3 if the third argument (the
      original string) is a literal, so convert it to a plain string.

  * Implementation changes:

    + '.comment()' is now a regular method.
    + Replace UnfinishedTag with functools.partial.
    + Delete UnfinishedComment, UnfinishedLiteral, UnfinishedTag.
    + Refactor methods to call self instead of doing ad hoc joins.
    + Merge 'make_tag()' into 'HTMLBuilder.tag()'. Make it call 'self' rather
      than joining strings.
    + Move 'empty_tags' to 'HTMLBuilder.void_tags'.
    + Move part of 'format_attrs()' to 'HTMLBuilder.optimize_attrs()', and
      merge '_attr_decode()' into it, and also None value handling. Move the
      compose dict local variable to a class attribute 'compose_attrs'.
    + Implement boolean attribute conversion in 'HTMLBuilder.optimize_attrs()'.
    + Refactor 'format_attrs()' to 'HTMLBuilder.render_attrs()'. Change the
      argument to a dict instead of keyword args. Delete the None handling
      because 'HTMLBuilder.optimize_attrs()' now does it.

- webhelpers.html.tags:

    * New class 'Link' is like 'link_to_if' but is lazily evaluated.
    * Delete 'title()'. It's too specific for a general-purpose library.
    * Delete 'xml_declaration()'.
    * Delete 'convert_boolean_attrs()' and 'css_classes()'. The HTML builder
      now does these itself.
    * When 'link_to_if' and 'link_to_unless' return just the label, escape it.
      Tag functions are always supposed to return literals.
    * The 'id_format' argument to the 'ModelTags' constructor now uses "{}"
      string formatting. It still accepts "%s" for backward compatibility and
      converts it to the newer format.
    * Add a space between the widget and the label when rendering 'checkbox()'
      or 'radio()' with the 'label' argument.
    * 'checkbox()' and 'radio()' have a new keyword argument 'label_class'.
      This sets the <label>'s class attribute.

    * Bugfixes:

      + Python 3's 'map()' behavior broke 'select()'.

    * Implementation changes:

      + Call 'HTML.tag()' rather than attribute access for a slight performance
        improvement.
      + Input helpers call '_input()' to render themselves. It subsumes the
        old '_set_input_attrs()' code.

- webhelpers.html.tools:

    * New home for 'update_params()'. Beta 1 had left it in the
      'unfinished' directory.

    * Implementation changes:

      + Unpack nested tag expression in 'button_to()'.
        

- Port doctests in 'html' subpackage to unit tests.

2.0b5 (2013-11-24)
------------------

- Port to Python 3.  Tested on Python 3.3.2 and 2.7.4.
- Depend on the 'six' distribution for Python 2/3 unification.
- Removed all "u" string prefixes so it should work on Python 3.2. (Prefixes in
  former doctests remain; these have not been supported as doctests since
  2.0b4.)

2.0b4 (2013-11-11)
------------------

- Change test suite to py.test, and convert doctests to unit tests. Some Python
  examples were left in the docs for documentation. Did not port the doctests
  in the 'html' subpackage because of the potential overhaul of that package.

- delete submodules:

  * media (moved ``choose_height()`` to misc. ``get_dimensions()`` has equivalents on
    PyPI; e.g., the ``dimensions`` and ``imagefacts`` distributions)

- webhelpers.containers:

  * Rename ``only_some_keys()`` to ``copy_keys()``, and ``except_keys()`` to 
    ``copy_keys_except()``, and ``extract_keys()`` to ``split_dict()``. In all
    these functions change the ``keys`` argument to ``\*keys``. This parallels
    a previous change to ``del_keys()`` in 2.0b3.

- webhelpers.html.tags:

  * The ``image()`` helper no longer accepts args 'path' or 'use_pil'. In
    WebHelpers these invoked the 'media' package to parse the width and
    height from the image file, but the 'media' package was not ported to
    WebHelpers2. It raises TypeError if these args are specified.

- webhelpers.text:

  * Change the argument signature of ``series()``. The items are now positional
    args, and the keyword args are renamed to ``conj`` and ``strict``.


2.0b3 (2013-04-07)
------------------

- Delete submodules:

  * html.converters (merged to html.tools)

- webhelpers.containers:

  * Rename ``del_quiet`` to ``del_keys``, and change to accept keys as
    positional arguments. 
  * Rename ``extract_keys`` to ``split_dict``.
  * Delete ``get_many``.

- webhelpers2.html.misc:

  * Delete ``format_number``. To display with thosands separators, use
    ``"{:,}".format(12346)`` (always comma) or ``"{:n}".format(12345)``
    (locale-specific).

- webhelpers.html.tags:

  * Delete ``required_legend()``.

- webhelpers2.html.tools: 

  * Merge 'webhelpers2.html.converters' into 'webhelpers2.html.tools'.
  * Rename ``format_paragraphs`` to ``text_to_html`` (from converters module).
  * Rename ``render`` to ``html_to_text`` (from converters module).
  * Bugfix in ``text_html``, should return a literal.

- webhelpers.misc:

  * Delete ``all``, ``any``, and ``no``.  Python >= 2.5 has builtins for the
    first two.
  * Rename ``convert_or_none`` to ``convert``.

- webhelpers.number:

  * Keep the individual statistic helpers but delete the container classes
    (``Stats`` and ``SimpleStats``).

- Delete the sample CSS stylesheet.


2.0b2 (2012-01-29)
------------------

- All HTML tag helpers now convert underscores to hyphens in attribute names. This
  is to support HTML5 "data-" attributes as keyword args. Trailing underscores
  are still removed ("class\_" -> "class"). (Bitbucket #55)

- webhelpers2.html.tools:

  * Delete 'highlighter' arg in ``highight`` helper. It has been deprecated
    since WebHelpers 1.0b2.


2.0b1 (2012-01-26)
------------------

- Import code and docs from WebHelpers 1.3. Source:
  https://bitbucket.org/bbangert/webhelpers/changeset/979fc4537c87c54eed933e5a84d43df51be88ff2
- Rename top-level package to ``webhelpers2``.
- Delete submodules: 

  * feedgenerator
  * html.grid
  * html.grid_demo
  * markdown
  * mimehelper
  * paginate
  * pylonslib (flash, grid, minify, secure_form)
  * textile
  * util

- webhelpers2.containers:
  
  * Delete Accumulator: use ``collections.defaultdict(list)`` in stdlib or 
    WebOb's '`MultiDict``. 
  * Delete UniqueAccumulator: use ``collections.defaultdict(set)`` in stdlib.

- webhelpers2.html.tags:

  * Delete Doctype: use simply "<!DOCTYPE html>" for HTML 5.
  * Rename sample stylesheet to 'webhelpers2/static/stylesheets/webhelpers2.css'.

- webhelpers2.misc:

  * Rename 'subclasses_only' to 'subclasses_of'.
  * Delete DeclarativeException and OverwriteError.

- Bugfix in leap year algorithm contributed by "rejoc" on GitHub.
  (``webhelpers2.date._is_leap_year()``)
- Moved 'update_params()' to the unfinished directory pending a new home; it
  was in the deleted util module.
