<commit_before># -*- coding: utf-8 -*-
#
# Copyright (C) 2006-2007 Edgewall Software
# All rights reserved.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
# are also available at http://genshi.edgewall.org/wiki/License.
#
# This software consists of voluntary contributions made by many
# individuals. For the exact contribution history, see the revision
# history and logs, available at http://genshi.edgewall.org/log/.

"""Support for programmatically generating markup streams from Python code using
a very simple syntax. The main entry point to this module is the `tag` object
(which is actually an instance of the ``ElementFactory`` class). You should
rarely (if ever) need to directly import and use any of the other classes in
this module.

Elements can be created using the `tag` object using attribute access. For
example:

>>> doc = tag.p('Some text and ', tag.a('a link', href='http://example.org/'), '.')
>>> doc
<Element "p">

This produces an `Element` instance which can be further modified to add child
nodes and attributes. This is done by "calling" the element: positional
arguments are added as child nodes (alternatively, the `Element.append` method
can be used for that purpose), whereas keywords arguments are added as
attributes:

>>> doc(tag.br)
<Element "p">
>>> print doc
<p>Some text and <a href="http://example.org/">a link</a>.<br/></p>

If an attribute name collides with a Python keyword, simply append an underscore
to the name:

>>> doc(class_='intro')
<Element "p">
>>> print doc
<p class="intro">Some text and <a href="http://example.org/">a link</a>.<br/></p>

As shown above, an `Element` can easily be directly rendered to XML text by
printing it or using the Python ``str()`` function. This is basically a
shortcut for converting the `Element` to a stream and serializing that
stream:

>>> stream = doc.generate()
>>> stream #doctest: +ELLIPSIS
<genshi.core.Stream object at ...>
>>> print stream
<p class="intro">Some text and <a href="http://example.org/">a link</a>.<br/></p>


The `tag` object also allows creating "fragments", which are basically lists
of nodes (elements or text) that don't have a parent element. This can be useful
for creating snippets of markup that are attached to a parent element later (for
example in a template). Fragments are created by calling the `tag` object, which
returns an object of type `Fragment`:

>>> fragment = tag('Hello, ', tag.em('world'), '!')
>>> fragment
<Fragment>
>>> print fragment
Hello, <em>world</em>!
"""

try:
    set
except NameError:
    from sets import Set as set

from genshi.core import Attrs, Namespace, QName, Stream, START, END, TEXT

__all__ = ['Fragment', 'Element', 'ElementFactory', 'tag']
__docformat__ = 'restructuredtext en'


class Fragment(object):
    """Represents a markup fragment, which is basically just a list of element
    or text nodes.
    """
    __slots__ = ['children']

    def __init__(self):
        """Create a new fragment."""
        self.children = []

    def __add__(self, other):
        return Fragment()(self, other)

    def __call__(self, *args):
        """Append any positional arguments as child nodes.
        
        :see: `append`
        """
        map(self.append, args)
        return self

    def __iter__(self):
        return self._generate()

    def __repr__(self):
        return '<%s>' % self.__class__.__name__

    def __str__(self):
        return str(self.generate())

    def __unicode__(self):
        return unicode(self.generate())

    def append(self, node):
        """Append an element or string as child node.
        
        :param node: the node to append; can be an `Element`, `Fragment`, or a
                     `Stream`, or a Python string or number
        """
        if isinstance(node, (Stream, Element, basestring, int, float, long)):
            # For objects of a known/primitive type, we avoid the check for
            # whether it is iterable for better performance
            self.children.append(node)
        elif isinstance(node, Fragment):
            self.children.extend(node.children)
        elif node is not None:
            try:
                map(self.append, iter(node))
            except TypeError:
                self.children.append(node)

    def _generate(self):
        for child in self.children:
            if isinstance(child, Fragment):
                for event in child._generate():
                    yield event
            elif isinstance(child, Stream):
                for event in child:
                    yield event
            else:
                if not isinstance(child, basestring):
                    child = unicode(child)
                yield TEXT, child, (None, -1, -1)

    def generate(self):
        """Return a markup event stream for the fragment.
        
        :rtype: `Stream`
        """
        return Stream(self._generate())


def _kwargs_to_attrs(kwargs):
    retval = {}
    for name, value in kwargs.items():
        name = name.rstrip('_').replace('_', '-')
        if value is not None and name not in retval:
            retval[QName(name)] = unicode(value)
    return Attrs(retval.items())


class Element(Fragment):
    """Simple XML output generator based on the builder pattern.

    Construct XML elements by passing the tag name to the constructor:

    >>> print Element('strong')
    <strong/>

    Attributes can be specified using keyword arguments. The values of the
    arguments will be converted to strings and any special XML characters
    escaped:

    >>> print Element('textarea', rows=10, cols=60)<commit_msg>Tweak to [854] to not change the ordering of attributes compared to how they were previously ordered, to avoid breaking any tests that rely on the order. See #216.<commit_after># -*- coding: utf-8 -*-
#
# Copyright (C) 2006-2007 Edgewall Software
# All rights reserved.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
# are also available at http://genshi.edgewall.org/wiki/License.
#
# This software consists of voluntary contributions made by many
# individuals. For the exact contribution history, see the revision
# history and logs, available at http://genshi.edgewall.org/log/.

"""Support for programmatically generating markup streams from Python code using
a very simple syntax. The main entry point to this module is the `tag` object
(which is actually an instance of the ``ElementFactory`` class). You should
rarely (if ever) need to directly import and use any of the other classes in
this module.

Elements can be created using the `tag` object using attribute access. For
example:

>>> doc = tag.p('Some text and ', tag.a('a link', href='http://example.org/'), '.')
>>> doc
<Element "p">

This produces an `Element` instance which can be further modified to add child
nodes and attributes. This is done by "calling" the element: positional
arguments are added as child nodes (alternatively, the `Element.append` method
can be used for that purpose), whereas keywords arguments are added as
attributes:

>>> doc(tag.br)
<Element "p">
>>> print doc
<p>Some text and <a href="http://example.org/">a link</a>.<br/></p>

If an attribute name collides with a Python keyword, simply append an underscore
to the name:

>>> doc(class_='intro')
<Element "p">
>>> print doc
<p class="intro">Some text and <a href="http://example.org/">a link</a>.<br/></p>

As shown above, an `Element` can easily be directly rendered to XML text by
printing it or using the Python ``str()`` function. This is basically a
shortcut for converting the `Element` to a stream and serializing that
stream:

>>> stream = doc.generate()
>>> stream #doctest: +ELLIPSIS
<genshi.core.Stream object at ...>
>>> print stream
<p class="intro">Some text and <a href="http://example.org/">a link</a>.<br/></p>


The `tag` object also allows creating "fragments", which are basically lists
of nodes (elements or text) that don't have a parent element. This can be useful
for creating snippets of markup that are attached to a parent element later (for
example in a template). Fragments are created by calling the `tag` object, which
returns an object of type `Fragment`:

>>> fragment = tag('Hello, ', tag.em('world'), '!')
>>> fragment
<Fragment>
>>> print fragment
Hello, <em>world</em>!
"""

try:
    set
except NameError:
    from sets import Set as set

from genshi.core import Attrs, Namespace, QName, Stream, START, END, TEXT

__all__ = ['Fragment', 'Element', 'ElementFactory', 'tag']
__docformat__ = 'restructuredtext en'


class Fragment(object):
    """Represents a markup fragment, which is basically just a list of element
    or text nodes.
    """
    __slots__ = ['children']

    def __init__(self):
        """Create a new fragment."""
        self.children = []

    def __add__(self, other):
        return Fragment()(self, other)

    def __call__(self, *args):
        """Append any positional arguments as child nodes.
        
        :see: `append`
        """
        map(self.append, args)
        return self

    def __iter__(self):
        return self._generate()

    def __repr__(self):
        return '<%s>' % self.__class__.__name__

    def __str__(self):
        return str(self.generate())

    def __unicode__(self):
        return unicode(self.generate())

    def append(self, node):
        """Append an element or string as child node.
        
        :param node: the node to append; can be an `Element`, `Fragment`, or a
                     `Stream`, or a Python string or number
        """
        if isinstance(node, (Stream, Element, basestring, int, float, long)):
            # For objects of a known/primitive type, we avoid the check for
            # whether it is iterable for better performance
            self.children.append(node)
        elif isinstance(node, Fragment):
            self.children.extend(node.children)
        elif node is not None:
            try:
                map(self.append, iter(node))
            except TypeError:
                self.children.append(node)

    def _generate(self):
        for child in self.children:
            if isinstance(child, Fragment):
                for event in child._generate():
                    yield event
            elif isinstance(child, Stream):
                for event in child:
                    yield event
            else:
                if not isinstance(child, basestring):
                    child = unicode(child)
                yield TEXT, child, (None, -1, -1)

    def generate(self):
        """Return a markup event stream for the fragment.
        
        :rtype: `Stream`
        """
        return Stream(self._generate())


def _kwargs_to_attrs(kwargs):
    attrs = []
    names = set()
    for name, value in kwargs.items():
        name = name.rstrip('_').replace('_', '-')
        if value is not None and name not in names:
            attrs.append((QName(name), unicode(value)))
            names.add(name)
    return Attrs(attrs)


class Element(Fragment):
    """Simple XML output generator based on the builder pattern.

    Construct XML elements by passing the tag name to the constructor:

    >>> print Element('strong')
    <strong/>

    Attributes can be specified using keyword arguments. The values of the
    arguments will be converted to strings and any special XML characters
    escaped:

    >>> print Element('textarea', rows=10, cols=60)
{'fraction_non_alphanumeric': 0.10742086144265697, 'fraction_numerical': 0.0031136481577581734, 'mean_word_length': 2.8737018425460636, 'pattern_counts': {'":': 0, '<': 51, '<?xml version=': 0, '>': 135, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3990213', 'n_tokens_mistral': 3170, 'n_tokens_neox': 3041, 'n_words': 1310}