
#######
History
#######


=====================================
Changes in 2.11 (released 07/29/2005)
=====================================

*A script xml2xsc.py has been added, that can be used to parse an
    XML file and generate a rudimentary XIST namespace from it.
*A DocType for XHTML 1.1 has been added (suggested by Elvelind
    Grandin).
*Line number information is now added when parsing HTML.
*The sorted method now supports the same arguments (cmp, key and
    reverse) as list.sort and sorted in Python 2.4.
*The walk doesn't yield the node directly, but yields a Cursor
    object now, with has several ways of referencing the node.
*New methods walknode, walkpath and walkindex have been added.
*Presenters use an iterator API instead of a stream API now.
    Dumping an XML tree presentation to the terminal can now start
    immediately instead of having to wait for the complete string to be
    formatted.
*Fixed a bug with element/attribute names that contained a .
    character. (This broke ll.xist.ns.fo.)
*Fixed a bug with xmlns attributes in nested elements. When an
    element ended the parser restored the wrong prefix mapping.
*The python-quotes demo has been updated to use the current
    version of AMK's XML file.
*Removed iterator stuff from ll.xist.xfind, as this is now part of
    the ll package/module.
*The function ToNode has been renamed to tonode.
*ll.xist.Context now longer subclasses list.
*ll.xist.ns.doc.explain will now try to output the objects in the
    order in which they appear in the Python source.
*The node methods find and findfirst have been removed.
*ll.xist.ns.cond now uses a sandbox dictionary in a converter
    context for evaluating expression.


=====================================
Changes in 2.10 (released 05/20/2005)
=====================================

*The content of the processing instruction ll.xist.ns.code.pyexec
    will not be executed at construction time, but at conversion time.
    The code in ll.xist.ns.code.pyexec or ll.xist.ns.code.pyeval will
    no longer be executed in the ll.xist.sandbox module (which has been
    removed), but in a sandbox dictionary in the converter context of
    the ll.xist.ns.code namespace.
*The tests have been ported to py.test.
*The method mapped is now callable without arguments. In this case
    a converter will be created on the fly. You can pass constructor
    arguments for this converter to mapped as keyword arguments.
*The publishing API has changed again:
    ll.xist.publishers.Publisher.publish now longer accepts an argument
    stream to which the byte strings are written, but it is a generator
    now. The publisher methods write and writetext have been renamed to
    encode and encodetext and return the encoded byte string, instead
    of writing it directly to the stream. There's a new generator
    method bytes for nodes now, which can be passed the same arguments
    as asBytes. These changes should help when using XIST in WSGI
    applications.
*The iterator returned from Element.__getitem__, Frag.__getitem__
    and the walk method now supports __getitem__ itself, so you can
    write table[html.tr][0] to get the first row from a table or
    page.walk(xsc.FindTypeAll(html.td))[-1] to get the last table cell
    from a complete HTML page.
*Several bugs in the namespaces ll.xist.ns.meta, ll.xist.ns.form
    and ll.xist.ns.specials have been fixed.
*The namespace modules ll.xist.ns.css and ll.xist.ns.cssspecials
    have been removed.


====================================
Changes in 2.9 (released 04/21/2005)
====================================

*XIST trees can now be pickled. The only restriction is that
    global attributes must come from a namespace that has been turned
    into a module via makemod, so that this module can be imported on
    unpickling.
*Two arguments of the walk method have been renamed: filtermode
    has been renamed to inmode and walkmode has been renamed to
    outmode. For these modes two new values are supported:

    ll.xist.xsc.walkindex
        The value passed to the filter function or yielded from the
        iterator is a list containing child indizes and attribute names
        that specify the path to the node in question.
    ll.xist.xsc.walkrootindex
        The filter function will be called with two arguments: The
        first is the root node of the tree (i.e. the node for which
        walk has been called), the second one is an index path (just
        like for ll.xist.xsc.walkindex). If used as an outmode a tuple
        with these two values will be yielded.


*Attribute mappings now support __getitem__, __setitem__ and
    __delitem__ with list arguments, i.e. you can do:
        >>> from ll.xist.ns import html
        >>> e = html.a("gurk", href=("hinz", "kunz"))
        >>> print e.attrs[["href", 0]]
        hinz
        >>> e.attrs[["href", 0]] = "hurz"
        >>> print e["href"]
        hurzkunz
        >>> del e.attrs[["href", 0]]
        >>> print e["href"]
        kunz

*XML attributes can now be accessed as Python attributes, i.e.
        >>> from ll.xist.ns import html
        >>> e = html.a("spam", href="eggs")
        >>> print e.attrs.href
        eggs

    (Don't confuse this with e.Attrs.href which is the attribute
    class.)

*Frag and Element now support Node subclasses as arguments to
    their __getitem__ method: An iterator for all children of the
    specified type will be returned.
*The encoding used for parsing now defaults to None. When reading
    from an URL and no default encoding has been specified the one from
    the Content-Type header will be used. If this still doesn't result
    in a usable encoding, "utf-8" will be used when parsing XML and
    "iso-8859-1" will be used when parsing broken HTML.
*All error and warning classes from ll.xist.errors have been
    merged into ll.xist.xsc. This avoids import problems with circular
    imports.
*The attributes showLocation and showPath of
    ll.xist.presenters.TreePresenter have been lowercased and
    presenters are properly reset after they've done their job.
*The class attribute xmlname will no longer be turned into a list
    containing the Python and the XML name, but will be the XML name
    only. You can get the Python name from foo.__class__.__name__.
*DeprecationWarnings for name and attrHandlers have finally been
    removed.
*Instances of ll.xist.xsc.Entity subclasses can now be compared.
    __eq__ simply checks if the objects are instances of the same
    class.


======================================
Changes in 2.8.1 (released 03/22/2005)
======================================

*Added a note about the package init file to the installation
    documentation.


====================================
Changes in 2.8 (released 01/03/2005)
====================================

*XIST requires Python 2.4 now.
*ll.xist.ns.specials.x has been renamed to
    ll.xist.ns.specials.ignore.
*ll.xist.utils.findAttr has been renamed to
    ll.xist.utils.findattr.
*ll.xist.xfind.item no longer handles slices.
*XFind has been enhanced to support item and slice operators, i.e.
    if foo is an XFind operator, foo[0] is an operator that will
    produce the first node from foo (if there is one). Negative values
    and slices are supported too.
*Operators can be chained via division: html.a/html.b is an
    operator that can be passed around and applied to a node.
*XIST requires the new core module and makes use of the new ??
    cooperative displayhook?? functionality defined there: If you
    install the displayhook you can tweak or replace
    ll.xist.presenters.hookpresenter to change the output.


====================================
Changes in 2.7 (released 11/24/2004)
====================================

*The transparent pixel used by ll.xist.ns.htmlspecials.pixel has
    been renamed to spc.gif to avoid problems with IE.
*Removed a debug print in ll.xist.xfind.Finder.__getitem__.
*ll.xist.xfind now has a new function item, that can be used to
    get a certain item or slice from an iterator. xfind.first and
    xfind.last have been changed to use xfind.item, so you now have to
    pass a default value to get the old behaviour.
*Obsolete options in ll.xist.options have been removed (and
    reprEncoding has been renamed to reprencoding).


======================================
Changes in 2.6.2 (released 06/06/2005)
======================================

*Fixed a bug in ll.xist.parsers.Parser.parse.


======================================
Changes in 2.6.1 (released 11/02/2004)
======================================

*Fixed a bug in ll.xist.xfind.Finder.__floordiv__.
*Restricted characters as defined in XML 1.1 will now be published
    as character references.


====================================
Changes in 2.6 (released 10/26/2004)
====================================

*ToNode now tries iterating through the value passed in, so it's
    now possible to pass iterators and generators (and generator
    expressions in Python 2.4) to Frag and Element constructors.
*A new API named XFind has been added for iterating through XML
    trees. XFind expressions look somewhat like XPath expressions but
    are pure Python expressions. For example finding all images inside
    links in an HTML page can be done like this:
        from ll.xist import parsers, xfind
        from ll.xist.ns import html
        node = parsers.parseURL("http://www.python.org/", tidy=True)
        for img in node//html.a/html.img:
           print img["src"]

    The module ll.xist.xfind contains several operators that can be
    used in XFind expressions.

*Parsing broken HTML is now done with the HTML parser from libxml2
    . The parsing functions no longer accept options for tidy, only the
    boolean value of the tidy argument is used.
*The publishing API has been simplified: Publication can now be
    done with a call to ll.xist.publishers.Publisher.publish, passing
    in a ll.xist.xsc.Node. Writing strings to the publisher output is
    now done with ll.xist.publishers.Publisher.write. The methods
    beginPublication and endPublication have been removed.
*The presentation API has been simplified in the same way: You'll
    get a presentation by calling: string = presenter.present(node).
    The methods beginPresentation and endPresentation have been
    removed.
*The parser now has the option to ignore illegal elements,
    attributes, processing instructions and entities. The default
    behaviour is to raise an exception, but this can now be
    reconfigured via Python's warning framework.
*The classmethod tokenize from ll.toxic has been moved to
    ll.xist.xsc.Namespace, so it's now possible to tokenize an XML
    string for other processing instructions as well.
*A new class ll.xist.xsc.NSPool has been added. An NSPool contains
    a pool of namespaces from which the parser selects the appropriate
    namespace once an xmlns attribute is encountered.
*The script xscmake.py (which has been unmaintained for a while
    now) has been removed.
*Elements hostname, tty, prompt and input were add to
    ll.xist.ns.doc.
*The method ll.xist.xsc.Attrs.set now returns the new attribute
    object.
*The visit method has been removed.
*ll.xist.xsc.FindOld has been removed.
*ll.xist.ns.xml.header has been renamed to
    ll.xist.ns.xml.declaration.


====================================
Changes in 2.5 (released 06/30/2004)
====================================

*Specifying content models for elements has seen major
    enhancements. The boolean class attribute empty has been replaced
    by an object model whose checkvalid method will be called for
    validating the element content.
*A new module ll.xist.sims has been added that provides a simple
    schema validation. Schema violations will be reported via Pythons
    warning framework.
*All namespace modules have been updated to use sims information.
    The SVG module has been updated to SVG 1.1. The docbook module has
    been updated to DocBook 4.3.
*It's possible to switch off validation during parsing and
    publishing.
*ll.xist.xsc.Frag and ll.xist.xsc.Element both have a __call__
    method with the same arguments as their constructors. Those methods
    will append content nodes (and set attributes for
    ll.xist.xsc.Element) and return self, so they can be used when
    creating an object tree. This makes it possible to put the
    attributes close to the tag name, instead of putting them at the
    end after the content.

    Instead of:
        node = html.table(
           html.tr(
              html.td("foo"),
              html.td("bar"),
           ),
           html.tr(
              html.td("spam"),
              html.td("eggs")
           ),
           class_="example"
        )

    you can now use the following:
        node = html.table(class_="example")(
           html.tr(
              html.td("foo"),
              html.td("bar"),
           ),
           html.tr(
              html.td("spam"),
              html.td("eggs")
           )
        )

*Experimental support for Holger Krekel's XPython has been added.
    Code might look like this:
        from ll.xist import xsc, converters
        from ll.xist.ns import html, meta

        import random

        c = converters.Converter()
        <c>:
           <html.html()>:
              <html.head()>:
                 <meta.contenttype()>: pass
                 <html.title()>:
                    xsc.append("The title")
              <html.body(class_="foo")>:
                 <html.h1()>:
                    flag = random.choice((0, 1))
                    if flag:
                       xsc.append("The foo page", class_="foo")
                    else:
                       xsc.append("The bar page", class_="bar")
                 <html.p()>:
                    if flag:
                       xsc.append("The foo content")
                    else:
                       xsc.append("The bar content")

        print c.lastnode.asBytes()

*Creating global attributes has been simplified. Passing an
    instance of ll.xist.xsc.Namespace.Attrs to an Element constructor
    now does the right thing:
        from ll.xist.ns import html, xml
        node = html.html(
           html.head(),
           xml.Attrs(lang="de"),
           lang="en",
        )

*Creating skeleton implementations of XIST namespaces is no longer
    done via XML conversion (i.e. the namespace module
    ll.xist.ns.xndl), but through the new module ll.xist.xnd. The
    script dtdxsc.py will automatically generate sims information.
*ll.xist.xsc.CharRef now inherits from ll.xist.xsc.Text too, so
    you don't have to special case CharRefs any more. When publishing,
    CharRefs will be handled like Text nodes.
*ll.xist.ns.meta.contenttype now has an attribute mimetype
    (defaulting to "text/html") for specifying the MIME type.
*ll.xist.ns.htmlspecials.caps has been removed.
*Registering elements in namespace classes has been rewritten to
    use a cache now.
*Pretty printing has been changed: Whitespace will only be added
    now if there are no text nodes in element content.
*Two mailing lists are now available: One for discussion about
    XIST and one for XIST announcements.


======================================
Changes in 2.4.1 (released 01/05/2004)
======================================

*Changed the xmlname of ll.xist.ns.jsp.directive_page back again
    (it's directive.page only for the XML form, which we don't use
    anyway.)
*Drop the default value for
    ll.xist.ns.jsp.directive_page.Attrs.language, as this attribute can
    only be used once.
*If an ll.xist.xsc.Prefixes object has a prefix mapping for a
    namespace it will return this prefix too, if asked for a prefix for
    a subclass of this namespace.


====================================
Changes in 2.4 (released 01/02/2004)
====================================

*The class ll.xist.parsers.Handler has been renamed to Parser and
    has been made reusable, i.e. it is possible to instantiate a parser
    once and use it multiple times for parsing. All the classes derived
    from xml.sax.xmlreader.InputSource have been dropped and the
    methods for parsing strings, URLs and files have been implemented
    as methods of the parser. Most of the arguments that had to be
    passed to the various parsing functions are passed to the parser
    constructor now. The basic parsing functionality is implemented by
    parsing streams instead of InputSources.
*Similar to the changes for parsing, publishers have been changed
    to be reusable and most arguments to the publishing functions are
    available as arguments to the publisher constructor.
*Now converter contexts are no longer bound to an element class,
    but to the context class defined by the element class, i.e. the
    attribute Context of the argument for Converter.__getitem__ will be
    used as the dictionary key. This makes it possible to use a class
    and it subclasses interchangeably (as long as the base class
    defines its own Context class and the subclasses don't overwrite
    it).
*Added a find functor FindTypeAllAttrs that searches content and
    attributes.
*Fixed the XML name for ll.xist.ns.jsp.directive_page.
*All character references in ll.xist.ns.ihtml that exist in
    ll.xist.ns.chars too have been removed.


====================================
Changes in 2.3 (released 12/08/2003)
====================================

*It's now possible to parse XML without generating location
    information for each node, by passing loc=False to the constructor
    of the Handler.
*The HTMLParser no longer complains about global attributes or
    xmlns.
*XIST now supports Tidylib in addition to mxTidy. If Tidylib is
    found it is preferred over mxTidy.
*It's possible now to pass arguments to tidy simple by passing an
    argument dictionary for the tidy argument in the parsing functions.
*The methods parsed and checkvalid have been separated.
*ll.xist.ns.htmlspecials.pixel and
    ll.xist.ns.htmlspecials.autopixel now check whether their color
    attribute is ok.
*The base URL is now set correctly when parsing from an URL even
    if the original URL does a redirect. (This requires ll.url version
    0.11.3).
*Namespace handling has been rewritten again, to be more standards
    compliant: Now there is no prefixes for entities and processing
    instructions any longer. Prefix mappings can be created much
    simpler, and they no longer contain any namespace stack for
    parsing, as this is now done by the parser itself.
    xsc.NamespaceAttrMixIn is gone too.
*The processing instructions exec_ and eval_ from ll.xist.ns.code
    have been renamed to pyexec and pyeval and import_ has been
    removed.
*CharRefs from ll.xist.ns.html have been moved to a new module
    named ll.xist.ns.chars.
*The method names beginPublication, endPublication and
    doPublication have been lowercased.


====================================
Changes in 2.2 (released 07/31/2003)
====================================

*Namespace handling has been completely rewritten. Namespaces are
    now classes derived from ll.xist.xsc.Namespace. Defining element
    classes can be done inside or outside the namespace class. If the
    element classes are defined outside the namespace class, they can
    be moved inside the namespace with a simple attribute assignment:
        class foo(xsc.Element):
           empty = False

        class xmlns(xsc.Namespace):
           xmlname = "foo"
           xmlurl = "http://www.foo.com/ns/foo"

        xmlns.foo = foo

    The methods elementkeys, iterelementkeys, elementvalues,
    iterelementvalues, elementitems and iterelementitems can be used
    for iterating through the element classes and their names. You can
    use the method element to get an element class with a certain name:
        >>> from ll.xist.ns import html
        >>> html.element("div")
        <element class ll.xist.ns.html/div at 0x824363c>

    For processing instructions, entities and character references
    similar methods are available.

    The method update can be used to add many element classes to a
    namespace at once, simply by passing a dictionary with those
    classes (use vars() to add everything that's defined inside your
    module). The method updatenew does the same, but copies only those
    attributes that don't exist in the namespace, updateexisting copies
    only those that do exist. You can turn a namespace into a module
    with makemod:
        from ll.xist import xsc

        class foo(xsc.Element):
           empty = False

        class xmlns(xsc.Namespace):
           xmlname = "foo"
           xmlurl = "http://www.foo.com/ns/foo"
        xmlns.makemod(vars())

    Put the above code into foo.py and you can do the following:
        >>> import foo
        >>> foo
        <namespace foo/xmlns name=u'foo' url=u'http://www.foo.com/ns/foo' with 1 elements from 'foo.py' at 0x81bfc14>

*getns has been dropped, so you always have to pass in a Namespace
    class where a namespace is required.
*For the ll.xist.ns.jsp.directive_page element automatic
    generation of the correct charset option in the contentType
    attribute is only done when there is a contentType attribute, as
    contentType is optional.
*The converter has a new property node. node can't be passed to
    conv but will be set to self by conv automatically. This makes it
    possible to access the ??document root?? during conversion.
*ll.xist.ns.htmlspecials.autoimg no longer touches existing width
    and height attributes. This means that %-formatting of the existing
    attributes is no longer done.
*Added a new class ll.xist.ns.htmlspecials.autopixel that works
    like ll.xist.ns.htmlspecials.pixel but inherits the size for the
    image specified via the src attribute.
*Frag and Element now support extended slices.
*Frag and Element now support the methods extend and __iadd__.
*For walking the tree the method walk has been completely
    rewritten and a new method visit has been added. For more info see
    the docstrings.
*Node now has two new methods copy and deepcopy and supports the
    copy module from the Python standard library.
*Calling mapped through conv has been removed. You again have to
    call mapped directly and pass a node and a converter.
*The HTML handling of the HTMLParser has been improved (it now
    uses code from xml.sax.drivers2.drv_sgmlop_html (which is part of
    PyXML)).
*The core functionality found in the script dtd2xsc.py has been
    moved to a class method ll.xist.ns.xndl.fromdtd in the
    ll.xist.ns.xndl namespace.
*ll.xist.parsers.ExpatParser is now a real subclass instead of an
    alias for xml.sax.expatreader.ExpatParser It reports unknown entity
    references to the application (if loading of external entities is
    switched off, which is done by ll.xist.parsers.Handler and only
    outside of attributes).
*Namespaces have been added for Zope's TAL and METAL
    specifications.
*A namespace has been added for XSL-FO.


======================================
Changes in 2.1.4 (released 06/13/2003)
======================================

*Remove the checks for attributes in attributes and moved the
    publication code for the full element into a separate method. This
    allows JSP tag library namespaces to simply overwrite publish to
    publish the element even inside attributes. (This is the same fix
    as in release 1.5.10)


======================================
Changes in 2.1.3 (released 05/07/2003)
======================================

*The methods sorted, reversed and shuffled have been rewritten so
    they no longer use sys.maxint. This change fixes those methods for
    64 bit platforms (reported by Giles Frances Hall)


======================================
Changes in 2.1.2 (released 02/27/2003)
======================================

*ll.xist.ns.struts_config11.plug_in now allows content (as the DTD
    states). (This is the same fix as in release 1.5.8.)


======================================
Changes in 2.1.1 (released 02/11/2003)
======================================

*Added a few elements and attributes to ll.xist.ns.doc: username,
    which is used for the name of a user account, xref, which is used
    for internal cross references and the attribute id for section,
    which specifies the target for an xref.


====================================
Changes in 2.1 (released 12/09/2002)
====================================

*Added a new namespace module ll.xist.ns.xndl that contains the ??
    XIST namespace definition language??, i.e. elements that describe
    an XIST namespace and can be used by various scripts to generate
    skeleton namespace modules. The first of these script is the DTD to
    namespace converter dtd2xsc.py.
*Added a new namespace module ll.xist.ns.tld that contains the
    definition for Java Server Pages Tag Library descriptors and a
    script tld2xsc.py that uses this namespace to generate namespace
    modules from tld files.
*Attr now supports the method filtered. This is used by without
    now. The arguments for without have changed, because handling
    global attributes was too ??magic??. A new method with has been
    added, with does the opposite of without, i.e. it removes all
    attributes that are not specified as parameters.
*The Python name of each Node subclass is now available as the
    class attribute pyname.
*To continue the great renaming withSep has been renamed to
    withsep.
*The namespace name for the ll.xist.ns.struts_html module has been
    fixed.
*The argument defaultEncoding for the various parsing functions
    has been renamed to encoding.


======================================
Changes in 2.0.8 (released 11/20/2002)
======================================

*ll.xist.ns.doc.getDoc has been renamed to getdoc.
*The CSS parser was dropping the % from percentage values. This
    has been fixed.


======================================
Changes in 2.0.7 (released 11/12/2002)
======================================

*xsc.Element.__nonzero__ can no longer fall back to
    xsc.Frag.__nonzero__. (this is the same fix as in 1.5.7).


======================================
Changes in 2.0.6 (released 11/11/2002)
======================================

*Performance optimizations.


======================================
Changes in 2.0.5 (released 11/11/2002)
======================================

*Fixed a bug in ll.xist.ns.specials.autoimg: Attributes were not
    converted before the size check was done (this is the same fix as
    in 1.5.5).


======================================
Changes in 2.0.4 (released 11/08/2002)
======================================

*Fixed a regression bug in ll.xist.ns.jsp.directive and several
    documentation issues.


======================================
Changes in 2.0.3 (released 10/30/2002)
======================================

*Fixed a few bugs in HTMLParser.
*Added DocBook conversion for several elements in ll.xist.ns.doc.
*Now the __init__.py file for the ll package is included.


======================================
Changes in 2.0.2 (released 10/21/2002)
======================================

*Fixed a bug in Frag.__rmul__ (by reusing __mul__).
*Fixed a bug with the backwards compatible prefix mapping:
    Defining element classes in exec processing instructions didn't
    work, because the prefixes object used for parsing wouldn't be
    updated when the namespace object is defined inside the processing
    instruction. Now using the default for the prefixes argument in
    calls to the parsing functions uses one global shared Prefixes
    instances where all the namespaces that are newly defined will be
    registered too.


======================================
Changes in 2.0.1 (released 10/17/2002)
======================================

*Fixed xscmake.py by removing the prefix handling. OldPrefixes
    will always be used for parsing now.


====================================
Changes in 2.0 (released 10/16/2002)
====================================

*XIST now requires at least Python 2.2.1.
*Attribute handling has been largely rewritten. Instead of a class
    attribute attrHandlers, the attributes are now defined through a
    nested class named Attrs inside the element. This class must be
    derived from ll.xist.Element.Attrs (or one of its subclasses if you
    want to inherit attributes from this class). Defining attributes is
    done through classes nested inside this attributes class and
    derived from any of the known attribute classes (like TextAttr,
    URLAttr etc.). The class name will be the attribute name (and can
    be overwritten with a class attribute xmlname. This makes it
    possible to have docstrings for attributes. Furthermore it's
    possible to define an attribute default value via the class
    attribute default, allowed values for the attribute via values,
    which is a list of allowed values, and whether the attribute is
    required or not via required.
*XIST now has real namespace support. The new class
    ll.xist.xsc.Prefixes can be used to define a mapping between
    prefixes and namespace names. This can be used for parsing and
    publishing. Namespace support is even available for entities and
    processing instruction.
*Global attributes are supported now. Namespace modules for the
    xml and xlink namespaces have been added (and ll.xist.xsc.XML was
    moved to ll.xist.ns.xml).
*A new namespace module for SVG 1.0 has been added:
    ll.xist.ns.svg.
*The HTML specific parts of ll.xist.ns.specials have been split
    off into a separate module ll.xist.ns.htmlspecials.
*Comparison of attributes with strings has been removed. You have
    to use __unicode__ or __str__ now before comparing.
*The HTMLParser now removes unknown attributes instead of
    complaining.
*There is a new parser class BadEntityParser, which is a SAX2
    parser that recognizes the character entities defined in HTML and
    tries to pass on unknown or malformed entities to the handler
    literally.
*To give all nodes a chance to do something after they have been
    parsed (e.g. to prepend the base URL for URLAttr nodes), the parser
    now calls the method parsed immediately after node creation. This
    is used for the new class StyleAttr, which uses the CSSTokenizer,
    to prepend the base URL to all URLs found in a style attribute.
*The pixel images have been moved to the directory px to make
    image URLs shorter.


======================================
Changes in 1.6.1 (released 08/25/2003)
======================================

*Updated to work with newer versions of ll.ansistyle.
*Updated the namespaces ll.xist.ns.struts_html and
    ll.xist.ns.struts_config11 to the state of Struts 1.1 final.


====================================
Changes in 1.6 (released 07/02/2003)
====================================

*Removed the default value for the className attribute in
    ll.xist.ns.struts_config11.action.
*Added an attribute type to
    ll.xist.ns.struts_config11.action_mapping.


=======================================
Changes in 1.5.13 (released 07/01/2003)
=======================================

*Implemented ll.xist.xsc.Namespace.__eq__, so that replacing a
    namespace in the registry really works.
*Added an attribute target to ll.xist.ns.html.area.


=======================================
Changes in 1.5.12 (released 06/17/2003)
=======================================

*Fixed a bug in the new ll.xist.ns.jsp.


=======================================
Changes in 1.5.11 (released 06/13/2003)
=======================================

*Updated ll.xist.ns.jsp to JSP 1.2.


=======================================
Changes in 1.5.10 (released 06/13/2003)
=======================================

*Remove the checks for attributes in attributes and moved the
    publication code for the full element into a separate method. This
    allows JSP tag library namespaces to simply overwrite publish to
    publish the element even inside attributes.


======================================
Changes in 1.5.9 (released 04/30/2003)
======================================

*Reregistering a namespace now properly overwrites the old version
    in xsc.namespaceRegistry.


======================================
Changes in 1.5.8 (released 02/27/2003)
======================================

*ll.xist.ns.struts_config11.plug_in now allows content (as the DTD
    states).


======================================
Changes in 1.5.7 (released 11/12/2002)
======================================

*xsc.Element.__nonzero__ can no longer fall back to
    xsc.Frag.__nonzero__.


======================================
Changes in 1.5.6 (released 11/11/2002)
======================================

*Performance optimizations.


======================================
Changes in 1.5.5 (released 11/11/2002)
======================================

*Fixed a bug in ll.xist.ns.specials.autoimg: Attributes were not
    converted before the size check was done.


======================================
Changes in 1.5.4 (released 09/30/2002)
======================================

*xscmake.py now tries to strip off a trailing xsc from the
    filename before it falls back to the extension html (The builtin
    extension mapping is still tried first).


======================================
Changes in 1.5.3 (released 09/25/2002)
======================================

*Added new processing instruction class ll.xist.ns.php.expression
    that generates a PHP print statement from its content.


======================================
Changes in 1.5.2 (released 09/19/2002)
======================================

*Removed the value magic from ll.xist.ns.form.checkbox as this
    conflicted with dynamic value values.


======================================
Changes in 1.5.1 (released 09/17/2002)
======================================

*Comparison of attributes with strings has been removed. You have
    to use __unicode__ or __str__ instead.
*The HTMLParser now removes unknown attributes instead of
    complaining.
*There is a new parser class BadEntityParser, which is a SAX2
    parser that recognizes the character entities defined in HTML and
    tries to pass on unknown or malformed entities to the handler
    literally.
*To give all nodes a chance to do something after they have been
    parsed (e.g. to prepend the base URL for URLAttr nodes), the parser
    now calls the method parsed() immediately after node creation. This
    is used for the new class StyleAttr, which uses the CSSTokenizer,
    to prepend the base url to all urls found in a style attribute.
*The HTMLParser now removes unknown attributes instead of
    complaining.
*There is a new parser class BadEntityParser, which is a SAX2
    parser that recognizes the character entities defined in HTML and
    tries to pass on unknown or malformed entities to the handler
    literally.
*To give all nodes a chance to do something after they have been
    parsed (e.g. to prepend the base URL for URLAttr nodes), the parser
    now calls the method parsed immediately after node creation. This
    is used for the new class StyleAttr, which uses the CSSTokenizer,
    to prepend to base URL to all URLs found in a style attribute.


======================================
Changes in 1.4.3 (released 04/29/2002)
======================================

*New namespace module xist.ns.struts_config11 allows to parse and
    modify Struts configuration files conforming to the Struts 1.1 DTD.


======================================
Changes in 1.4.2 (released 03/22/2002)
======================================

*Updated xscmake.py to be compatible with the new url module.
*xist.ns.jsp.directive_page now automatically sets the contentType
    on publishing.


======================================
Changes in 1.4.1 (released 03/21/2002)
======================================

*Removed TidyURLInputSource. Now it's possible to pass a tidy flag
    to the remaining functions parseString, parseFile and parseURL to
    specify whether the source should be tidied.
*To prevent an element from being registered in a Namespace the
    class attribute register can be used now. This makes it possible to
    have a name for the element even when it's not registered.
*xist.ns.form elements now have all the attributes that the
    corresponding elements from xist.ns.html have.
*Removed the old xist.url from the Windows distribution.


====================================
Changes in 1.4 (released 03/18/2002)
====================================

*Reimplemented URL handling again. Now the new global module url
    is used for that.


======================================
Changes in 1.3.1 (released 03/14/2002)
======================================

*Added a method pretty to Node for generating a pretty printable
    version of the node.
*xsc.Node.name no longer is a class method, but a class attribute,
    that will be set at class instantiation time by the meta class.


====================================
Changes in 1.3 (released 02/12/2002)
====================================

*Ported to Python 2.2. Node is now derived from object, Frag from
    list and there's a new class Attrs which is derived from dict for
    the attribute mappings. All presenters have been adapted to work
    with Attrs. In addition to the usual dictionary methods and
    operators Attrs has a method without that returns a copy of the
    Attrs instance with some specified attributes removed.
*All the node classes now have a new method walk that generates
    all nodes in the tree using the new generator feature of Python
    2.2.
*Also a new method walkPath has been added that works the same as
    walk but yields the complete path to each node as a list.
*Added a class block to xist.ns.jsp. The content of the block
    instance will simply be enclosed in a {} block. xist.ns.php got
    such a class too.
*Added a new module xist.ns.ihtml for i-mode HTML.
*Added new modules xist.ns.css and xist.ns.cssspecials for
    generating CSS.
*Now the various attributes of the Converter object are collected
    in a ConverterState object and it's possible to push and pop those
    states, i.e. it's now easy to temporarily modify a converter object
    during a convert call and revert back to a previous state
    afterwards.
*parseURL and parseTidyURL now have an additional parameter
    headers which is a list of string pairs specifying additional
    headers to be passed in with the request.
*parseString has an additional parameter systemId which will be
    the system id of the InputSource.
*The distribution now includes the makefile and the XML source
    files so now the distribution can rebuild ifself.
*Various other small bugfixes and enhancements.


======================================
Changes in 1.2.5 (released 12/03/2001)
======================================

*Added a new element contentscripttype to xist.ns.meta that
    generates a <meta http-equiv="Content-Script-Type" ...> element.
*xist.ns.doc.explain now generates anchor elements for the class,
    function and method description, so now the links on the XIST
    webpages work.
*Docstrings and documentation has been reworked. Now
    xist.ns.doc.pyref no longer implies a font change. Use the classes
    xist.ns.doc.module, xist.ns.doc.class, xist.ns.doc.method,
    xist.ns.doc.function and xist.ns.doc.arg to mark up your Python
    identifiers.
*Added the attributes type and key to
    xist.ns.struts_config.data_source.


======================================
Changes in 1.2.4 (released 11/23/2001)
======================================

*Added the deprecated attributes start to xist.ns.html.ol and
    value to xist.ns.html.li.


======================================
Changes in 1.2.3 (released 11/22/2001)
======================================

*Added missing asPlainString methods to Comment and DocType.


======================================
Changes in 1.2.2 (released 11/16/2001)
======================================

*xist.url.URL.fileSize and xist.url.URL.imageSize now use the
    warning framework to report errors.
*There is a new presenter named CodePresenter that dumps the tree
    as Python source code.
*The filenames of the pixel images used by xist.ns.specials.pixel
    have changed. These images are now included.


======================================
Changes in 1.2.1 (released 10/08/2001)
======================================

*URLs that are completely dynamic will now be left in peace when
    parsing or publishing.


====================================
Changes in 1.2 (released 10/03/2001)
====================================

*xist.ns.meta.keywords and xist.ns.meta.description no longer call
    asPlainString on their content. This makes it possible to e.g.
    generate the keywords via JSP:
        >>> from xist import parsers
        >>> from xist.ns import meta, jsp
        >>> s = '<keywords>' + \
        ...     '<?jsp:expression "foo"?>' + \
        ...     '</keywords>'
        >>> e = parsers.parseString(s)
        >>> print e.conv().asBytes()
        <meta name="keywords" content="<%= "foo" %>" />

*When an element occurs inside an attribute during publishing,
    there won't be an exception raised any more. Instead the content of
    the element will be published. This fixes problems with
    abbreviation entities inside attributes.
*xist.parsers.TidyURLInputSource now uses the new experimental
    eGenix mx Extension package, which includes a Python port of tidy.
*__repr__ now uses the new class presenters.PlainPresenter which
    gives a little more info than the default __repr__.
*URL handling has been changed again. Upto now, URLAttr had an
    additional instance attribute base, which was the ??base?? file/URL
    from which the attribute was parsed. Now the base URL will be
    directly incorporated into the URL. You can pass the base URL to
    all the parsing functions. Similar to that when publishing you can
    specify a base URL. All URLs in the tree will be output relative to
    this base URL. Joining URLs is now done via __div__ and no longer
    via __add__. This makes it more consistent with fileutils. The plan
    is to make URLs string like immutable objects and to merge them
    with fileutils.Filename.
*xist.ns.specials.php has been moved to its own module
    (xist.ns.php). This module provided additional convenience
    processing instructions (just like xist.ns.jsp does).


======================================
Changes in 1.1.3 (released 09/17/2001)
======================================

*The global namespace registry now keeps a sequential list of all
    registered namespaces, which will be used by the parser when
    searching for names. This gives a predictable search order even
    without using Namespaces and its pushNamespace method: modules
    imported last will be searched first.
*Processing instructions are now allowed inside attributes when
    publishing.
*xist.ns.docbooklite has been renamed to xist.ns.doc. It can now
    generate HTML and Docbook output and has improved a lot. The XIST
    web pages now use this for automatic documentation generation. The
    doc example has been removed.
*xist.url.URL now has a new method info that returns the headers
    for the file/URL.
*xist.url.URL now has a methods fileSize and imageSize too.
*xist.ns.jsp.directive_page now has new attribute session.


======================================
Changes in 1.1.2 (released 08/21/2001)
======================================

*__repr__ now uses the new class presenters.PlainPresenter which
    gives a little more info than the default __repr__.


======================================
Changes in 1.1.1 (released 08/01/2001)
======================================

*Small bugfix in presenters.strProcInst
*fixed xist.ns.struts_html.option to allow content


====================================
Changes in 1.1 (released 07/19/2001)
====================================

*Sequences in constructor arguments for Frag and Element are again
    expanded and it's again possible to pass dictionaries in an Element
    constructor to specify attributes. As sequences are always
    unpacked, the method extend is gone. This works for append and
    insert too.
*Node and Frag implement __mul__ and __rmul__, so you can do stuff
    like:
        html.br()*5

    This returns a Frag with five times to same node.

*Arguments for the converter constructor can be passed to
    xist.xsc.Node.conv now, so it's possible to do stuff like this:
        from xist.ns import code
        print code.Eval("return converter.lang") \
           .conv(lang="en").asBytes()

    which will print en.

*The option XHTML for the publishers has been changed to
    lowercase.
*xist.ns.html.html will automatically generate a lang and xml:lang
    attribute when the converter has a language set.


====================================
Changes in 1.0 (released 06/18/2001)
====================================

*New module for WML 1.3.
*The publishing interface has changed internally and publishing
    should be faster now.
*Publishers now support a new parameter: usePrefix, which
    specifies if namespace prefixes should be output for the element
    names.
*Part of the implementation of the publishing stuff has been moved
    to C, so now you'll need a C compiler to install XIST.
*When publishing ", it will now only be replaced with &quot;
    inside attributes.
*All the asHTML methods now have an additional argument converter.
    This makes it possible to implement different processing modes or
    stages for new elements. All currently implemented elements and
    entities ignore this argument, but pass it on in the call to their
    childrens' asHTML method. As the name asHTML no longer makes sense,
    asHTML has been renamed to convert.
*There is now a tool dtd2xsc.py in the scripts directory that
    creates a skeleton XIST module from a DTD (this requires xmlproc
    from the PyXML package).
*New preliminary module for DocBook 4.12. (Incomplete: convert
    methods and Unicode character entities are missing; any volunteers
    for implementing 375 classes?)
*New module ruby.py that implements the W3C Ruby draft.
*sql.py has been removed from XIST, but is available as a separate
    module.
*The parsing interface has been changed. Parsing is now done with
    the functions parseFile, parseString, parseURL and parseTidyURL in
    the module parsers. It's now possible to specify which parser
    should be used for parsing by passing a SAX2 parser instance to any
    of these functions. XIST now includes a rudimentary SAX2 driver for
    sgmlop and a rudimentary HTML parser that emits SAX2 events.
*The python-quotes example has been updated to work with expat.
*Added a new example: media.
*All abbreviation entities have been moved to a new module
    abbr.py.
*All the modules that provide new elements and entitites have been
    moved to a subpackage ns.
*Frag and Element now have new methods sorted, reversed, filtered
    and shuffled that return sorted, reversed, filtered and shuffled
    versions of the Frag/Element object.
*New namespace modules ns/jsp.py and ns/struts_html.py have been
    added that allow you to use JSP and Struts tags with XIST.
*A new method asText was added, that returns the node as a
    formatted plain ASCII text (this requires that w3m is installed.)
*make.py has been renamed to xscmake.py and moved to the scripts
    directory, it will be installed as a callable script with python
    setup.py install_scripts.
*xscmake.py has a new option --files/-f. The argument is a file
    containing a list of filenames (one name per line) that should be
    converted.
*xscmake.py has a new option -r/--parser for specifying which
    parser to use. Allowed values are sgmlop and expat.
*xscmake.py has a new option -n/--namespace that can be used for
    appending Namespace objects to the Namespaces object used by
    xscmake.py.
        xscmake.py -n html -n spam eggs.xsc

    With this call the parser will find element classes from the module
    with the prefix name spam before those from html and those before
    anything else.

*xist.url.URL no longer has an attribute ext. file and ext are
    merged.
*The special treatment of sequences as constructor arguments to
    Frag and Element has been removed, so XIST will no longer remove
    one level of nesting. If you still want that, use a * argument.
*Frag and Element now have a new method mapped, that recursively
    maps the nodes through a function. This is like convert but via an
    external function.
*Attribute handling has been improved thanks to a suggestion by
    Hartmut Goebel: Element.__getitem__ now always works as long as the
    attribute name is legal. If the attribute is not set, an empty
    attribute will be returned. All empty attributes will be considered
    as being not set and so hasAttr returns 0 for them, and publish
    doesn't publish them. This simplifies several very common cases:
    +Copying an attribute from one element to another works
        regardless of whether the attribute is set or not;
    +Testing for an attributes presence can now be done much
        simpler: if element["attrname"] instead of if element.hasAttr
        ("attrname") (which still works, and should be a little
        faster);
    +When you construct a DOM tree and the presence or absence of
        an attribute is tied to a condition, you can construct the
        attribute in advance and use it afterwards in the tree
        construction:
            if condition:
               align = "right"
            else:
               align = None
            node = html.div("spam", align=align)

        So, when the condition is false, the node will not have the
        attribute align set.


*xist.ns.cond.If (and xist.ns.cond.ElIf) can now be used to test
    for attributes of the converter. I.e. it's possible to write the
    following XML:
        <if lang="en">Title
        <elif lang="de">berschrift
        </if>

*URL handling has be completely changed and is much, much simpler
    now. There are no more path markers. To specify an URL that is
    relative to the current directory use the scheme root (e.g. root:
    main.css).


======================================
Changes in 0.4.7 (released 11/24/2000)
======================================

*Fixed a bug in the entity handling.
*Added a few deprecated elements and attributes to the html
    module.
*Improved the publishing of attributes. Now all attribute values
    will be published. For boolean attributes no value will be
    published for XHTML==0 and the attribute name will be used for
    XHTML==1 or XHTML==2.
*Element.compact now works (better) ;).
*Incorparated many bug fixes from Hartmut Goebel.
*Implemented xsc.Element.copyDefaultAttrs, which copies unset
    attributes over from a dictionary (simplifies implementing
    specials.plaintable and specials.plainbody)
*providers.Provider.pushNamespace now handles multiple arguments
    which may be Namespace objects or modules (in which case,
    module.namespace will be pushed)
*providers.Providers.popNamespace can now pop multiple namespaces
    at once.
*providers.TidyURIProvider now uses os.popen3 for piping the file
    through tidy, so now there will be no more temporary files. The
    call to tidy now includes options that hopefully make the output
    more suited to XIST.
*Incorparated a new url.py by Hartmut Goebel, that fixes many
    problem (e.g. optimizing http://server/foo/bar/../../baz.gif now
    works.)
*make.py includes a new option --path for adding directories to
    sys.path.


======================================
Changes in 0.4.6 (released 11/03/2000)
======================================

*Now uses sgmlop.XMLParser instead of sgmlop.SGMLParser, so case
    is preserved.
*Fixed another regression from the URL to string conversion
    change.


======================================
Changes in 0.4.5 (released 11/01/2000)
======================================

*Converting URLs to nodes is now done in ToNode, so URL objects
    can be used everywhere.
*Fixed a few bugs in Text._strtext and URLAttr._str.


======================================
Changes in 0.4.4 (releases 10/27/2000)
======================================

*Now testing if characters can be encoded with the specified
    encoding is done directy. This means, that escaping unencodable
    characters now works even with exotic encodings (tested with
    JapaneseCodecs-1.0.1.tar.gz).
*The URLAttr constructor now can handle a single parameter of the
    type URL.
*The URL to string conversion function have changed: URL.asString
    returns the URL with path markers, URL.asPlainString returns the
    URL without path markers.
*Added the i18n attribute to the font element.
*Fixed the clashes between the class names for the elements and
    entities sub and sup in html.py.
*Several small enhancements and bug fixes contributed by Hartmut
    Goebel.


======================================
Changes in 0.4.3 (released 10/19/2000)
======================================

*Now processing instruction classes are registered in the same way
    as elements and entities are.
*The leaf nodes (Text, Comment, ProcInst) are now considered
    immutable. This means that their asHTML method can simply return
    self, because now those nodes can be shared between trees.
    Functionality for manipulation the objects is provided by a mixin
    class very similar to UserString. All this results in a speedup of
    about 10% for the python-quotes example.
*Small optimizations in the asHTML methods of Element and Frag
    optimized away many calls to append, extend and ToNode and result
    in a speedup of about 30% for the python-quotes example. One
    consequence of this is that Null objects will no longer be ignored.


======================================
Changes in 0.4.2 (released 09/24/2000)
======================================

*New elements keywords and description in meta.py.
*Fixed a bug in Namespace.register, now setting name=None to
    prevent an element from being registered works again.


======================================
Changes in 0.4.1 (released 09/21/2000)
======================================

*A new module named meta.py has been created, that simplifies
    generating meta tags.
*Various small bugfixes.


====================================
Changes in 0.4 (released 09/19/2000)
====================================

*XIST now requires at least Python 2.0b1.
*A new bugfixed version of the sgmlop source is available from the
    FTP site.
*XIST now completely supports Unicode. For output any encoding
    known to Python can be used, so now you can output your HTML in
    ASCII, Latin-1, UTF-8, UTF-16, ...
*All publishers have been updated to support Unicode. The
    publishing interface has been streamlined (encoding and XHTML
    parameters are now attributes of the publisher).
*asString will now always return a Unicode string. If you want a
    byte string use asBytes instead, where the encoding can be
    specified as an argument.
*There an additional publisher class FilePublisher, which can be
    used for publishing to a file (or anything else that has a write
    and a writelines method, and is supported by the stream writer
    available through codecs.lookup).
*Element and attribute names are no longer converted to lowercase.
    If you have an attribute name which clashes with a Python keyword
    (e.g. class) append an underscore (_), which will be removed before
    accessing the attribute. This is the ??official?? Python method for
    handling these cases.
*Elements and entities are no longer registered one by one. Now
    you can build Namespace objects which are used for searching and
    there are pushNamespace and popNamespace functions in XSC.xsc. For
    more info, see the source.
*Image size calculation has been removed from html.img and
    html.input. Use specials.autoimg and specials.autoinput for that.
*__getitem__, __setitem__ and __delitem of Frag and Element now
    accepts a list as an argument. The method will be applied
    recursively, i.e. e[[0, 1, "foo", 2] is the same as e[0][1]["foo"]
    [2].
*The deprecated module db.py no longer exists. Useful functions
    and elements from db.py have been moved to sql.py and form.py
    respectively.
*When using xsc.make the encoding and XHTML parameters to use can
    now be specified on the command line (e.g. --encoding utf-8 --xhtml
    2)
*Handling of multiline <?xsc-eval?> and <?xsc-exec?> has been
    enhanced, although, XIST will not be able to guess the correct
    indentation in all cases. As a workarround simply add a Python
    comment to the beginning:
        <?xsc-exec
           for i in xrange(10):
              do(i)
        ?>

    won't work
        <?xsc-exec
           #
           for i in xrange(10):
              do(i)
        ?>

    will.

*Make functionality has been moved to make.py, as certain modules
    can't be used as the main script, because reimporting them in
    processing instructions won't work. Now you can simply call
        make.py --import xist.html --import spam eggs.xsc

*There is a new module cond.py, that contains elements that can be
    used for conditionals:
        <?xsc-exec a=42?>
        <if cond="a==21">
           <b>foo</b>
        <elif cond="a==42"/>
           <i>bar</i>
        <else/>
           baz
        </if>



======================================
Changes in 0.3.9 (released 08/10/2000)
======================================

*sgmlop will now be found either via import sgmlop or via from
    xml.parsers import sgmlop.


======================================
Changes in 0.3.8 (released 07/14/2000)
======================================

*Fixed a bug in URLAttr.publish, which prevented URLAttr from
    working at all.


======================================
Changes in 0.3.7 (released 07/06/2000)
======================================

*Fixed a bug in html.img and html.input. Now image size
    calculation works again.


======================================
Changes in 0.3.6 (released 07/04/2000)
======================================

*Fixed a bug in Node._matches, which resulted in a non working
    find.


======================================
Changes in 0.3.5 (released 07/02/2000)
======================================

*The documentation example has been enhanced. Now documenting
    methods works.
*When the member elementname in the element class is set before
    calling registerElement, this element name will be used for the
    element. This allows custom names even when using
    registerAllElements.
*Comparison of scheme and server in URLs is done case insensitive
    (as RFC 2068 requires.)
*Image size calculation is now done in asString and not in asHTML.
    This allows to write faster code. Old method:
        e = html.div(html.img(...),gurk.hurz()).asHTML().asString()

    New method
        e = html.div(html.img(...),gurk.hurz().asHTML()).asString()

*Image size calculation is now done for <input type="image">. The
    size attribute is set to the image width.
*Manipulating the path in an URL is now done via the usual
    __setitem__/__getitem__ stuff, which keeps the path in a consistent
    state.
        >>> from xist.URL import URL
        >>> u = URL("/foo/*/../bar/baz.gif")
        >>> del u[1]
        >>> u
        URL(scheme='server', path=['bar'], file='baz', ext='gif')

*findNodes (which has been shortened to find) has an additional
    argument test, which can be a test function that will be called
    when the node passes all other tests.
*asString no longer generates a string directly, but uses the new
    method publish, which has an additional argument publisher, to
    which the strings to be output are passed.


======================================
Changes in 0.3.4 (released 05/31/2000)
======================================

*Location information is now copied over in clone, asHTML and
    compact where appropriate, so you know even in the HTML tree where
    something came from.
*xsc.repransi can now have three values:
    +0: coloring is off
    +1: coloring is on for a dark background
    +2: coloring is on for a light background

    All repransi variables are now arrays with two strings, the first
    for dark, the second for light.



======================================
Changes in 0.3.3 (released 05/30/2000)
======================================

*The workaround for the trailing CDATA bug in sgmlop has been
    removed, so now you'll need a newer version of sgmlop (included in
    PyXML 0.5.5.1)


====================
Changes before 0.3.3
====================

*These changes predate written history.
