degal/html.py
author Tero Marttila <terom@fixme.fi>
Wed, 10 Jun 2009 23:33:28 +0300
changeset 84 891545a38a2b
parent 80 f4b637ae775c
child 144 97505a789003
permissions -rw-r--r--
change utils.LazyProperty to store the cached value using obj.__dict__
52
3071d0709c4a start writing some kind of nested-HTML-tag-generators magic to use instead of templates :)
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     1
"""
61
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
     2
    Generating XHTML output
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
     3
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
     4
    XXX: use a 'real' XML builder?
52
3071d0709c4a start writing some kind of nested-HTML-tag-generators magic to use instead of templates :)
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     5
"""
3071d0709c4a start writing some kind of nested-HTML-tag-generators magic to use instead of templates :)
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     6
3071d0709c4a start writing some kind of nested-HTML-tag-generators magic to use instead of templates :)
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     7
from cgi import escape
80
f4b637ae775c fix html to have a separate Container type, but also special-case tuples, lists and genexps
Tero Marttila <terom@fixme.fi>
parents: 78
diff changeset
     8
import itertools as _itertools, types as _types
52
3071d0709c4a start writing some kind of nested-HTML-tag-generators magic to use instead of templates :)
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     9
53
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
    10
class IRenderable (object) :
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
    11
    """
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
    12
        Something that's renderable as the contents of a HTML tag
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
    13
    """
52
3071d0709c4a start writing some kind of nested-HTML-tag-generators magic to use instead of templates :)
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    14
53
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
    15
    def render_raw_lines (self, indent=u'\t') :
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
    16
        """
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
    17
            Render the indented lines for tag and contents, without newlines
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
    18
        """
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
    19
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
    20
        abstract
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
    21
61
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
    22
    def render_lines (self, indent=u'\t', newline=u'\n') :
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
    23
        """
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
    24
            Render full output lines with given newlines
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
    25
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
    26
            >>> list(Tag('xx', 'yy').render_lines())
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
    27
            [u'<xx>\\n', u'\\tyy\\n', u'</xx>\\n']
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
    28
        """
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
    29
77
2a53c5ade434 misc. fixes, it runs now, but HTML output is corrupt (no flattening)
Tero Marttila <terom@fixme.fi>
parents: 76
diff changeset
    30
        for line in self.render_raw_lines(indent=indent) :
61
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
    31
            yield line + newline
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
    32
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
    33
    def render_unicode (self, **render_opts) :
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
    34
        """
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
    35
            Render full tag as a single unicode string
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
    36
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
    37
            >>> Tag('xx', 'yy').render_unicode()
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
    38
            u'<xx>\\n\\tyy\\n</xx>\\n'
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
    39
        """
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
    40
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
    41
        return "".join(self.render_lines(**render_opts))
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
    42
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
    43
    def render_str (self, encoding='ascii', **render_opts) :
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
    44
        """
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
    45
            Render full tag as an encoded string
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
    46
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
    47
            >>> Tag('xx', 'yy').render_str()
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
    48
            '<xx>\\n\\tyy\\n</xx>\\n'
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
    49
        """
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
    50
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
    51
        return self.render_unicode(**render_opts).encode(encoding)
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
    52
69
5b53fe294034 add render_file method for html.IRenderable
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    53
    def render_out (self, stream, encoding=None, **render_opts) :
61
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
    54
        """
69
5b53fe294034 add render_file method for html.IRenderable
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    55
            Render output into the given stream, encoding using the given encoding if given.
61
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
    56
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
    57
            >>> from StringIO import StringIO; buf = StringIO(); Tag('xx', 'yy').render_out(buf, 'ascii'); buf.getvalue()
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
    58
            '<xx>\\n\\tyy\\n</xx>\\n'
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
    59
        """
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
    60
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
    61
        for line in self.render_lines(**render_opts) :
69
5b53fe294034 add render_file method for html.IRenderable
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    62
            if encoding :
5b53fe294034 add render_file method for html.IRenderable
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    63
                line = line.encode(encoding)
5b53fe294034 add render_file method for html.IRenderable
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    64
5b53fe294034 add render_file method for html.IRenderable
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    65
            stream.write(line)
61
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
    66
    
69
5b53fe294034 add render_file method for html.IRenderable
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    67
    def render_file (self, file, encoding=None, **render_opts) :
5b53fe294034 add render_file method for html.IRenderable
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    68
        """
5b53fe294034 add render_file method for html.IRenderable
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    69
            Render output to given file, overwriteing anything already there
5b53fe294034 add render_file method for html.IRenderable
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    70
        """
5b53fe294034 add render_file method for html.IRenderable
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    71
77
2a53c5ade434 misc. fixes, it runs now, but HTML output is corrupt (no flattening)
Tero Marttila <terom@fixme.fi>
parents: 76
diff changeset
    72
        self.render_out(file.open_write(encoding), **render_opts)
69
5b53fe294034 add render_file method for html.IRenderable
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    73
61
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
    74
    # default output
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
    75
    __str__ = render_str
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
    76
    __unicode__ = render_unicode
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
    77
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
    78
    # default .render method
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
    79
    render = render_unicode
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
    80
78
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    81
class Container (IRenderable) :
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    82
    """
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    83
        A container holds a sequence of other renderable items.
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    84
    """
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    85
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    86
    @classmethod
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    87
    def process_contents (cls, contents) :
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    88
        """
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    89
            Postprocess contents iterable to return new list.
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    90
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    91
            Items that are None will be omitted from the return value.
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    92
80
f4b637ae775c fix html to have a separate Container type, but also special-case tuples, lists and genexps
Tero Marttila <terom@fixme.fi>
parents: 78
diff changeset
    93
            Certain core sequence types will be recognized and flattened for output: tuples, lists, and generators.
f4b637ae775c fix html to have a separate Container type, but also special-case tuples, lists and genexps
Tero Marttila <terom@fixme.fi>
parents: 78
diff changeset
    94
78
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    95
            >>> list(Container.process_contents([]))
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    96
            []
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    97
            >>> list(Container.process_contents([None]))
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    98
            []
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
    99
            >>> list(Container.process_contents([u'foo']))
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   100
            [u'foo']
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   101
        """
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   102
        
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   103
        for content in contents :
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   104
            if content is None :
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   105
                continue
80
f4b637ae775c fix html to have a separate Container type, but also special-case tuples, lists and genexps
Tero Marttila <terom@fixme.fi>
parents: 78
diff changeset
   106
            
f4b637ae775c fix html to have a separate Container type, but also special-case tuples, lists and genexps
Tero Marttila <terom@fixme.fi>
parents: 78
diff changeset
   107
            # Hardcoded list of special-case nested contents
f4b637ae775c fix html to have a separate Container type, but also special-case tuples, lists and genexps
Tero Marttila <terom@fixme.fi>
parents: 78
diff changeset
   108
            elif isinstance(content, (_types.TupleType, _types.ListType, _types.GeneratorType)) :
f4b637ae775c fix html to have a separate Container type, but also special-case tuples, lists and genexps
Tero Marttila <terom@fixme.fi>
parents: 78
diff changeset
   109
                for subcontent in cls.process_contents(content) :
f4b637ae775c fix html to have a separate Container type, but also special-case tuples, lists and genexps
Tero Marttila <terom@fixme.fi>
parents: 78
diff changeset
   110
                    yield subcontent
f4b637ae775c fix html to have a separate Container type, but also special-case tuples, lists and genexps
Tero Marttila <terom@fixme.fi>
parents: 78
diff changeset
   111
78
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   112
            else :
80
f4b637ae775c fix html to have a separate Container type, but also special-case tuples, lists and genexps
Tero Marttila <terom@fixme.fi>
parents: 78
diff changeset
   113
                # normal, handle as IRenderable/unicode data
78
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   114
                yield content
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   115
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   116
    def __init__ (self, *contents) :
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   117
        """
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   118
            Construct this container with the given sub-items
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   119
        """
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   120
        
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   121
        # store postprocessed
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   122
        self.contents = list(self.process_contents(contents))
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   123
    
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   124
    def render_raw_lines (self, **render_opts) :
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   125
        """
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   126
            Render our contents as a series of non-indented lines, with the contents handling indentation themselves.
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   127
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   128
            >>> list(Container(5).render_raw_lines())
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   129
            [u'5']
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   130
            >>> list(Container('line1', 'line2').render_raw_lines())
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   131
            [u'line1', u'line2']
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   132
            >>> list(Container('a', Tag('b', 'bb'), 'c').render_raw_lines())
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   133
            [u'a', u'<b>', u'\\tbb', u'</b>', u'c']
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   134
            >>> list(Container(Tag('hr'), Tag('foo')('bar')).render_raw_lines())
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   135
            [u'<hr />', u'<foo>', u'\\tbar', u'</foo>']
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   136
        """
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   137
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   138
        for content in self.contents :
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   139
            if isinstance(content, IRenderable) :
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   140
                # sub-items
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   141
                for line in content.render_raw_lines(**render_opts) :
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   142
                    yield line
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   143
            
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   144
            else :
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   145
                # escape raw values
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   146
                yield escape(unicode(content))
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   147
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   148
    def __repr__ (self) :
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   149
        return 'Container(%s)' % ', '.join(repr(c) for c in self.contents)
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   150
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   151
class Tag (Container) :
53
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   152
    """
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   153
        A HTML tag, with attributes and contents, which can a mixture of data and other renderables(tags).
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   154
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   155
        Provides various kinds of rendering output
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   156
    """
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   157
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   158
    @staticmethod
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   159
    def process_attrs (attrs) :
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   160
        """
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   161
            Postprocess attributes.
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   162
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   163
            Key-value pairs where the value is None will be ommitted, and any trailing underscores in the key omitted.
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   164
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   165
            TODO: only remove one underscore
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   166
78
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   167
            >>> dict(Tag.process_attrs(dict()))
53
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   168
            {}
78
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   169
            >>> dict(Tag.process_attrs(dict(foo='bar')))
53
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   170
            {'foo': 'bar'}
78
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   171
            >>> dict(Tag.process_attrs(dict(class_='bar', frob=None)))
53
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   172
            {'class': 'bar'}
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   173
        """
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   174
78
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   175
        return ((k.rstrip('_'), v) for k, v in attrs.iteritems() if v is not None)
53
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   176
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   177
    def __init__ (self, name, *contents, **attrs) :
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   178
        """
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   179
            Construct tag with given name/attributes or contents.
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   180
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   181
            The filtering rules desribed in process_contents/process_attrs apply.
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   182
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   183
            >>> Tag('foo')
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   184
            Tag('foo')
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   185
            >>> Tag('foo', 'quux')
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   186
            Tag('foo', 'quux')
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   187
            >>> Tag('foo', 'quux', bar=5)
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   188
            Tag('foo', 'quux', bar=5)
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   189
            >>> Tag('foo', class_='ten')
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   190
            Tag('foo', class='ten')
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   191
        """
78
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   192
        
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   193
        # store contents as container
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   194
        super(Tag, self).__init__(*contents)
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   195
        
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   196
        # store postprocessed stuff
53
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   197
        self.name = name
78
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   198
        self.attrs = dict(self.process_attrs(attrs))
53
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   199
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   200
    def __call__ (self, *contents, **attrs) :
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   201
        """
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   202
            Return a new Tag with this tag's attributes and contents, as well as the given attributes/contents.
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   203
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   204
            The filtering rules desribed in process_contents/process_attrs apply.
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   205
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   206
            >>> Tag('foo')('bar')
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   207
            Tag('foo', 'bar')
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   208
            >>> Tag('a', href='index.html')("Home")
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   209
            Tag('a', 'Home', href='index.html')
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   210
            >>> Tag('bar', None)(5, foo=None, class_='bar')
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   211
            Tag('bar', 5, class='bar')
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   212
            >>> Tag('a')('b')('c')(asdf=5)
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   213
            Tag('a', 'b', 'c', asdf=5)
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   214
            >>> t1 = Tag('a'); t2 = t1('b'); t1
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   215
            Tag('a')
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   216
        """
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   217
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   218
        # merge attrs/contents
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   219
        # XXX: new_attrs is not an iterator...
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   220
        new_attrs = dict(_itertools.chain(self.attrs.iteritems(), attrs.iteritems()))
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   221
        new_contents = _itertools.chain(self.contents, contents)
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   222
        
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   223
        # build new tag
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   224
        return Tag(self.name, *new_contents, **new_attrs)
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   225
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   226
    @staticmethod
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   227
    def format_attr (name, value) :
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   228
        """
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   229
            Format a single HTML tag attribute
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   230
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   231
            >>> Tag.format_attr('name', 'value')
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   232
            u'name="value"'
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   233
            >>> Tag.format_attr('this', '<a"b>')
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   234
            u'this="&lt;a&quot;b&gt;"'
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   235
            >>> Tag.format_attr('xx', 1337)
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   236
            u'xx="1337"'
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   237
        """
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   238
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   239
        return u'%s="%s"' % (name, escape(unicode(value), True))
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   240
 
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   241
    def render_attrs (self) :
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   242
        """
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   243
            Return the HTML attributes string
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   244
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   245
            >>> Tag('x', foo=5, bar='<').render_attrs()
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   246
            u'foo="5" bar="&lt;"'
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   247
        """
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   248
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   249
        return " ".join(self.format_attr(n, v) for n, v in self.attrs.iteritems())
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   250
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   251
    def render_raw_lines (self, indent=u'\t') :
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   252
        """
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   253
            Render the tag and indented content
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   254
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   255
            >>> list(Tag('xx', 'yy', zz='foo').render_raw_lines(indent=' '))
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   256
            [u'<xx zz="foo">', u' yy', u'</xx>']
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   257
        """
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   258
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   259
        # render attr string, including preceding space
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   260
        attrs_stuff = (" " + self.render_attrs()) if self.attrs else ""
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   261
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   262
        if self.contents :
78
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   263
            # wrapping tags
53
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   264
            yield u"<%s%s>" % (self.name, attrs_stuff)
78
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   265
            
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   266
            # subcontents
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   267
            for line in super(Tag, self).render_raw_lines(indent=indent) :
53
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   268
                yield indent + line
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   269
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   270
            yield u"</%s>" % (self.name, )
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   271
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   272
        else :
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   273
            # singleton tag
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   274
            yield u"<%s%s />" % (self.name, attrs_stuff)
52
3071d0709c4a start writing some kind of nested-HTML-tag-generators magic to use instead of templates :)
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   275
    
3071d0709c4a start writing some kind of nested-HTML-tag-generators magic to use instead of templates :)
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   276
53
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   277
    def __repr__ (self) :
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   278
        return 'Tag(%s)' % ', '.join(
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   279
            [
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   280
                repr(self.name)
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   281
            ] + [
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   282
                repr(c) for c in self.contents
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   283
            ] + [
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   284
                '%s=%r' % (name, value) for name, value in self.attrs.iteritems()
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   285
            ]
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   286
        )
52
3071d0709c4a start writing some kind of nested-HTML-tag-generators magic to use instead of templates :)
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   287
53
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   288
class Text (IRenderable) :
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   289
    """
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   290
        Raw HTML text
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   291
    """
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   292
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   293
    def __init__ (self, line) :
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   294
        """
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   295
            Initialize to render as the given lines
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   296
        """
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   297
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   298
        self.lines = [line]
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   299
    
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   300
    def render_raw_lines (self, indent=u'\t') :
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   301
        return self.lines
52
3071d0709c4a start writing some kind of nested-HTML-tag-generators magic to use instead of templates :)
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   302
61
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   303
class XHTMLDocument (IRenderable) :
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   304
    """
78
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   305
        A full XHTML document with XML header, doctype, head and body.
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   306
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   307
        XXX: current rendering is a bit of a kludge
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   308
61
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   309
        <?xml version="..." encoding="..." ?>
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   310
        <!DOCTYPE ...>
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   311
        
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   312
        <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   313
            <head>
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   314
                ...
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   315
            </head>
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   316
            <body>
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   317
                ...
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   318
            </body>
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   319
        </html>
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   320
    """
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   321
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   322
    def __init__ (self, 
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   323
        head, body,
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   324
        xml_version='1.0', xml_encoding='utf-8', 
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   325
        doctype='html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"',
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   326
        html_xmlns='http://www.w3.org/1999/xhtml', html_lang='en'
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   327
    ) :
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   328
        # store
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   329
        self.xml_version = xml_version
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   330
        self.xml_encoding = xml_encoding
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   331
        self.doctype = doctype
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   332
        
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   333
        # build the document
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   334
        self.document = Tag('html', **{'xmlns': html_xmlns, 'xml:lang': html_lang})(
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   335
            Tag('head', head),
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   336
            Tag('body', body),
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   337
        )
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   338
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   339
    def render_raw_lines (self, **render_opts) :
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   340
        """
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   341
            Render the two header lines, and then the document
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   342
        """
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   343
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   344
        yield '<?xml version="%s" encoding="%s" ?>' % (self.xml_version, self.xml_encoding)
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   345
        yield '<!DOCTYPE %s>' % (self.doctype)
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   346
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   347
        for line in self.document.render_raw_lines(**render_opts) :
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   348
            yield line
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   349
    
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   350
    def _check_encoding (self, encoding) :
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   351
        if encoding and encoding != self.xml_encoding :
76
e22d9f699081 misc. fixes
Tero Marttila <terom@fixme.fi>
parents: 69
diff changeset
   352
            raise ValueError("encoding mismatch: %r should be %r" % (encoding, self.xml_encoding))
61
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   353
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   354
    def render_str (self, encoding=None, **render_opts) :
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   355
        """
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   356
            Wrap render_str to verify that the right encoding is used
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   357
        """
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   358
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   359
        self._check_encoding(encoding)
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   360
        
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   361
        return super(XHTMLDocument, self).render_str(self.xml_encoding, **render_opts)
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   362
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   363
    def render_out (self, stream, encoding=None, **render_opts) :
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   364
        """
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   365
            Wrap render_out to verify that the right encoding is used
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   366
        """
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   367
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   368
        self._check_encoding(encoding)
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   369
        
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   370
        return super(XHTMLDocument, self).render_out(stream, self.xml_encoding, **render_opts)
fad360dd01da rework html a bit to move the render_* funcs to IRenderable, add XHTMLDocument (ugh), missing flatten
Tero Marttila <terom@fixme.fi>
parents: 53
diff changeset
   371
52
3071d0709c4a start writing some kind of nested-HTML-tag-generators magic to use instead of templates :)
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   372
class TagFactory (object) :
3071d0709c4a start writing some kind of nested-HTML-tag-generators magic to use instead of templates :)
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   373
    """
53
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   374
        Build Tags with names give as attribute names
52
3071d0709c4a start writing some kind of nested-HTML-tag-generators magic to use instead of templates :)
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   375
    """
3071d0709c4a start writing some kind of nested-HTML-tag-generators magic to use instead of templates :)
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   376
53
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   377
    def __getattr__ (self, name) :
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   378
        """
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   379
            Get a Tag object with the given name, but no contents
52
3071d0709c4a start writing some kind of nested-HTML-tag-generators magic to use instead of templates :)
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   380
53
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   381
            >>> TagFactory().a(href='bar')('quux')
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   382
            Tag('a', 'quux', href='bar')
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   383
        """
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   384
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   385
        return Tag(name)
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   386
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   387
# pretty names
78
d580323b4bfa fix html/templates to use a Container type (inherited by Tag) for flat lists of tags
Tero Marttila <terom@fixme.fi>
parents: 77
diff changeset
   388
container = Container
53
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   389
tag = Tag
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   390
tags = TagFactory()
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   391
raw = Text
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   392
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   393
# testing
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   394
if __name__ == '__main__' :
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   395
    import doctest
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   396
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   397
    doctest.testmod()
14d73f544764 expressive HTML-rendering module with doctests
Tero Marttila <terom@fixme.fi>
parents: 52
diff changeset
   398