Commits

Lynn Rees committed 48305f4

- rework documentation

Comments (0)

Files changed (18)

depends/docs_requirements.txt

+sphinx
+sphinxcontrib.spelling
+lxml>=1.1.1
+stuf>=0.8.14

depends/fabfile.py

+# -*- coding: utf-8 -*-
+'''webstring fabfile'''
+
+from fabric.api import prompt, local, settings, env, lcd
+
+regup = '../setup.py register sdist --format=bztar,gztar,zip upload'
+nodist = 'rm -rf ../dist'
+sphinxup = '../setup.py upload_sphinx'
+
+
+def _promptup():
+    prompt('Enter tag: ', 'tag')
+    with settings(warn_only=True):
+        local('hg tag "%(tag)s"' % env)
+        local('hg push ssh://hg@bitbucket.org/lcrees/webstring')
+        local('hg push github')
+
+
+def _test(val):
+    truth = val in ['py26', 'py27', 'py31', 'py32', 'pypy']
+    if truth is False:
+        raise KeyError(val)
+    return val
+
+
+def docs():
+    with lcd('../docs/'):
+        local('make clean')
+        local('make html')
+        local('make linkcheck')
+        local('make doctest')
+
+
+def tox():
+    '''
+    test webstring
+    '''
+    with lcd('../'):
+        local('tox')
+
+
+def update_docs():
+    '''
+    update webstring docs
+    '''
+    docs()
+    with settings(warn_only=True):
+        local('hg ci -m docmerge')
+        local('hg push ssh://hg@bitbucket.org/lcrees/webstring')
+        local('hg push github')
+    local(sphinxup)
+
+
+def tox_recreate():
+    '''
+    recreate webstring test env
+    '''
+    with lcd('../'):
+        prompt(
+            'Enter testenv: [py26, py27, py31, py32, pypy]',
+            'testenv',
+            validate=_test,
+        )
+        local('tox --recreate -e %(testenv)s' % env)
+
+
+def release():
+    '''
+    release webstring
+    '''
+    docs()
+    local('hg update pu')
+    local('hg update next')
+    local('hg merge pu; hg ci -m automerge')
+    local('hg update maint')
+    local('hg merge default; hg ci -m automerge')
+    local('hg update default')
+    local('hg merge next; hg ci -m automerge')
+    local('hg update pu')
+    local('hg merge default; hg ci -m automerge')
+    _promptup()
+    local(regup)
+    local(sphinxup)
+    local(nodist)
+
+
+def releaser():
+    '''
+    webstring releaser
+    '''
+    docs()
+    _promptup()
+    local(regup)
+    local(sphinxup)
+    local(nodist)
+
+
+def inplace():
+    '''
+    in-place webstring
+    '''
+    docs()
+    with settings(warn_only=True):
+        local('hg push ssh://hg@bitbucket.org/lcrees/webstring')
+        local('hg push github')
+    local('../setup.py sdist --format=bztar,gztar,zip upload')
+    local(sphinxup)
+    local(nodist)
+
+
+def release_next():
+    '''
+    release webstring from next branch
+    '''
+    docs()
+    local('hg update maint')
+    local('hg merge default; hg ci -m automerge')
+    local('hg update default')
+    local('hg merge next; hg ci -m automerge')
+    local('hg update next')
+    local('hg merge default; hg ci -m automerge')
+    _promptup()
+    local(regup)
+    local(sphinxup)
+    local(nodist)

depends/requirements.txt

+stuf>=0.8.14
+lxml>=1.1.1

pips/docs_requirements.txt

-sphinx
-sphinxcontrib.spelling
-lxml>=1.1.1
-stuf>=0.8.14

pips/fabfile.py

-# -*- coding: utf-8 -*-
-'''webstring fabfile'''
-
-from fabric.api import prompt, local, settings, env, lcd
-
-regup = '../setup.py register sdist --format=bztar,gztar,zip upload'
-nodist = 'rm -rf ../dist'
-sphinxup = '../setup.py upload_sphinx'
-
-
-def _promptup():
-    prompt('Enter tag: ', 'tag')
-    with settings(warn_only=True):
-        local('hg tag "%(tag)s"' % env)
-        local('hg push ssh://hg@bitbucket.org/lcrees/webstring')
-        local('hg push github')
-
-
-def _test(val):
-    truth = val in ['py26', 'py27', 'py31', 'py32', 'pypy']
-    if truth is False:
-        raise KeyError(val)
-    return val
-
-
-def docs():
-    with lcd('../docs/'):
-        local('make clean')
-        local('make html')
-        local('make linkcheck')
-        local('make doctest')
-
-
-def tox():
-    '''
-    test webstring
-    '''
-    with lcd('../'):
-        local('tox')
-
-
-def update_docs():
-    '''
-    update webstring docs
-    '''
-    docs()
-    with settings(warn_only=True):
-        local('hg ci -m docmerge')
-        local('hg push ssh://hg@bitbucket.org/lcrees/webstring')
-        local('hg push github')
-    local(sphinxup)
-
-
-def tox_recreate():
-    '''
-    recreate webstring test env
-    '''
-    with lcd('../'):
-        prompt(
-            'Enter testenv: [py26, py27, py31, py32, pypy]',
-            'testenv',
-            validate=_test,
-        )
-        local('tox --recreate -e %(testenv)s' % env)
-
-
-def release():
-    '''
-    release webstring
-    '''
-    docs()
-    local('hg update pu')
-    local('hg update next')
-    local('hg merge pu; hg ci -m automerge')
-    local('hg update maint')
-    local('hg merge default; hg ci -m automerge')
-    local('hg update default')
-    local('hg merge next; hg ci -m automerge')
-    local('hg update pu')
-    local('hg merge default; hg ci -m automerge')
-    _promptup()
-    local(regup)
-    local(sphinxup)
-    local(nodist)
-
-
-def releaser():
-    '''
-    webstring releaser
-    '''
-    docs()
-    _promptup()
-    local(regup)
-    local(sphinxup)
-    local(nodist)
-
-
-def inplace():
-    '''
-    in-place webstring
-    '''
-    docs()
-    with settings(warn_only=True):
-        local('hg push ssh://hg@bitbucket.org/lcrees/webstring')
-        local('hg push github')
-    local('../setup.py sdist --format=bztar,gztar,zip upload')
-    local(sphinxup)
-    local(nodist)
-
-
-def release_next():
-    '''
-    release webstring from next branch
-    '''
-    docs()
-    local('hg update maint')
-    local('hg merge default; hg ci -m automerge')
-    local('hg update default')
-    local('hg merge next; hg ci -m automerge')
-    local('hg update next')
-    local('hg merge default; hg ci -m automerge')
-    _promptup()
-    local(regup)
-    local(sphinxup)
-    local(nodist)

pips/requirements.txt

-stuf>=0.8.14
-lxml>=1.1.1

tests/__init__.py

+# -*- coding: utf-8 -*-

tests/doctest_text.py

+# -*- coding: utf-8 -*-
+'''Doctests for webstring text'''
+
+def _test():
+    '''
+    >>> from webstring import Template
+    >>> example = Template("""<rss version="2.0">
+    ...  <channel>
+    ...   <title>Example</title>
+    ...   <link>http://www.example.org/</link>
+    ...   <description>RSS Example</description>
+    ...   <language>en-us</language>
+    ...   $$cpubdate<pubDate>$month$ $day$, $year$</pubDate>$$
+    ...   $$lastbuilddate<lastBuildDate>$month$ $day$, $year$</lastBuildDate>$$
+    ...   $$item<item>
+    ...    <title>$title$</title>
+    ...    <link>$link$</link>
+    ...    <guid isPermaLink="true">$guid$</guid>
+    ...    <description>$description$</description>
+    ...    <pubDate>$ipubdate$</pubDate>
+    ...   </item>
+    ...  $$</channel>
+    ... </rss>""", format='text')
+    >>> example.exclude('cpubdate') 
+    >>> print example
+    <rss version="2.0">
+     <channel>
+      <title>Example</title>
+      <link>http://www.example.org/</link>
+      <description>RSS Example</description>
+      <language>en-us</language>
+      <lastBuildDate> , </lastBuildDate>
+      <item>
+       <title></title>
+       <link></link>
+       <guid isPermaLink="true"></guid>
+       <description></description>
+       <pubDate></pubDate>
+      </item>
+     </channel>
+    </rss>
+    >>> example.include('cpubdate') 
+    >>> print example
+    <rss version="2.0">
+     <channel>
+      <title>Example</title>
+      <link>http://www.example.org/</link>
+      <description>RSS Example</description>
+      <language>en-us</language>
+      <pubDate> , </pubDate>
+      <lastBuildDate> , </lastBuildDate>
+      <item>
+       <title></title>
+       <link></link>
+       <guid isPermaLink="true"></guid>
+       <description></description>
+       <pubDate></pubDate>
+      </item>
+     </channel>
+    </rss>
+    >>> example.cpubdate %= {'month':'June', 'day':'06', 'year':'2006'}
+    >>> print example
+    <rss version="2.0">
+     <channel>
+      <title>Example</title>
+      <link>http://www.example.org/</link>
+      <description>RSS Example</description>
+      <language>en-us</language>
+      <pubDate>June 06, 2006</pubDate>
+      <lastBuildDate> , </lastBuildDate>
+      <item>
+       <title></title>
+       <link></link>
+       <guid isPermaLink="true"></guid>
+       <description></description>
+       <pubDate></pubDate>
+      </item>
+     </channel>
+    </rss>
+    >>> example.lastbuilddate %= {'month':'June', 'day':'06', 'year':'2006'}
+    >>> print example
+    <rss version="2.0">
+     <channel>
+      <title>Example</title>
+      <link>http://www.example.org/</link>
+      <description>RSS Example</description>
+      <language>en-us</language>
+      <pubDate>June 06, 2006</pubDate>
+      <lastBuildDate>June 06, 2006</lastBuildDate>
+      <item>
+       <title></title>
+       <link></link>
+       <guid isPermaLink="true"></guid>
+       <description></description>
+       <pubDate></pubDate>
+      </item>
+     </channel>
+    </rss>
+    >>> example.item.description.text = 'Example of assigning text to a field.' 
+    >>> print example
+    <rss version="2.0">
+     <channel>
+      <title>Example</title>
+      <link>http://www.example.org/</link>
+      <description>RSS Example</description>
+      <language>en-us</language>
+      <pubDate>June 06, 2006</pubDate>
+      <lastBuildDate>June 06, 2006</lastBuildDate>
+      <item>
+       <title></title>
+       <link></link>
+       <guid isPermaLink="true"></guid>
+       <description>Example of assigning text to a field.</description>
+       <pubDate></pubDate>
+      </item>
+     </channel>
+    </rss>
+    >>> example.item.link.text = 'http://www.example.com/rss/5423093'
+    >>> print example
+    <rss version="2.0">
+     <channel>
+      <title>Example</title>
+      <link>http://www.example.org/</link>
+      <description>RSS Example</description>
+      <language>en-us</language>
+      <pubDate>June 06, 2006</pubDate>
+      <lastBuildDate>June 06, 2006</lastBuildDate>
+      <item>
+       <title></title>
+       <link>http://www.example.com/rss/5423093</link>
+       <guid isPermaLink="true"></guid>
+       <description>Example of assigning text to a field.</description>
+       <pubDate></pubDate>
+      </item>
+     </channel>
+    </rss>
+    >>> example.item.title.text = 'Example Title: First Example'
+    >>> example.item.ipubdate.text = 'June 6, 2006'
+    >>> print example
+    <rss version="2.0">
+     <channel>
+      <title>Example</title>
+      <link>http://www.example.org/</link>
+      <description>RSS Example</description>
+      <language>en-us</language>
+      <pubDate>June 06, 2006</pubDate>
+      <lastBuildDate>June 06, 2006</lastBuildDate>
+      <item>
+       <title>Example Title: First Example</title>
+       <link>http://www.example.com/rss/5423093</link>
+       <guid isPermaLink="true"></guid>
+       <description>Example of assigning text to a field.</description>
+       <pubDate>June 6, 2006</pubDate>
+      </item>
+     </channel>
+    </rss>
+    >>> example.item.guid.text = 'http://www.example.com/rss/5423093'
+    >>> print example
+    <rss version="2.0">
+     <channel>
+      <title>Example</title>
+      <link>http://www.example.org/</link>
+      <description>RSS Example</description>
+      <language>en-us</language>
+      <pubDate>June 06, 2006</pubDate>
+      <lastBuildDate>June 06, 2006</lastBuildDate>
+      <item>
+       <title>Example Title: First Example</title>
+       <link>http://www.example.com/rss/5423093</link>
+       <guid isPermaLink="true">http://www.example.com/rss/5423093</guid>
+       <description>Example of assigning text to a field.</description>
+       <pubDate>June 6, 2006</pubDate>
+      </item>
+     </channel>
+    </rss>
+    >>> example.reset()
+    >>> print example
+    <rss version="2.0">
+     <channel>
+      <title>Example</title>
+      <link>http://www.example.org/</link>
+      <description>RSS Example</description>
+      <language>en-us</language>
+      <pubDate> , </pubDate>
+      <lastBuildDate> , </lastBuildDate>
+      <item>
+       <title></title>
+       <link></link>
+       <guid isPermaLink="true"></guid>
+       <description></description>
+       <pubDate></pubDate>
+      </item>
+     </channel>
+    </rss>
+    >>> example %= {
+    ... 'cpubdate':{'month':'June', 'day':'06', 'year':'2006'}, 
+    ... 'lastbuilddate':{'month':'June', 'day':'06', 'year':'2006'},
+    ... 'item':{'title':'Example Title: First Example',
+    ...     'link':'http://www.example.com/rss/5423093',
+    ...     'guid':'http://www.example.com/rss/5423093',
+    ...     'description':'Example of assigning text to a field.',
+    ...     'ipubdate':'June 6, 2006'}}
+    >>> print example
+    <rss version="2.0">
+     <channel>
+      <title>Example</title>
+      <link>http://www.example.org/</link>
+      <description>RSS Example</description>
+      <language>en-us</language>
+      <pubDate>June 06, 2006</pubDate>
+      <lastBuildDate>June 06, 2006</lastBuildDate>
+      <item>
+       <title>Example Title: First Example</title>
+       <link>http://www.example.com/rss/5423093</link>
+       <guid isPermaLink="true">http://www.example.com/rss/5423093</guid>
+       <description>Example of assigning text to a field.</description>
+       <pubDate>June 6, 2006</pubDate>
+      </item>
+     </channel>
+    </rss>
+    >>> print example.current
+    <rss version="2.0">
+     <channel>
+      <title>Example</title>
+      <link>http://www.example.org/</link>
+      <description>RSS Example</description>
+      <language>en-us</language>
+      <pubDate>June 06, 2006</pubDate>
+      <lastBuildDate>June 06, 2006</lastBuildDate>
+      <item>
+       <title>Example Title: First Example</title>
+       <link>http://www.example.com/rss/5423093</link>
+       <guid isPermaLink="true">http://www.example.com/rss/5423093</guid>
+       <description>Example of assigning text to a field.</description>
+       <pubDate>June 6, 2006</pubDate>
+      </item>
+     </channel>
+    </rss>
+    >>> print example.default
+    <rss version="2.0">
+     <channel>
+      <title>Example</title>
+      <link>http://www.example.org/</link>
+      <description>RSS Example</description>
+      <language>en-us</language>
+      <pubDate> , </pubDate>
+      <lastBuildDate> , </lastBuildDate>
+      <item>
+       <title></title>
+       <link></link>
+       <guid isPermaLink="true"></guid>
+       <description></description>
+       <pubDate></pubDate>
+      </item>
+     </channel>
+    </rss>
+    >>> example.reset()
+    >>> print example + example
+    <rss version="2.0">
+     <channel>
+      <title>Example</title>
+      <link>http://www.example.org/</link>
+      <description>RSS Example</description>
+      <language>en-us</language>
+      <pubDate> , </pubDate>
+      <lastBuildDate> , </lastBuildDate>
+      <item>
+       <title></title>
+       <link></link>
+       <guid isPermaLink="true"></guid>
+       <description></description>
+       <pubDate></pubDate>
+      </item>
+     </channel>
+    </rss><rss version="2.0">
+     <channel>
+      <title>Example</title>
+      <link>http://www.example.org/</link>
+      <description>RSS Example</description>
+      <language>en-us</language>
+      <pubDate> , </pubDate>
+      <lastBuildDate> , </lastBuildDate>
+      <item>
+       <title></title>
+       <link></link>
+       <guid isPermaLink="true"></guid>
+       <description></description>
+       <pubDate></pubDate>
+      </item>
+     </channel>
+    </rss>
+    >>> print example.item + example.item
+    <item>
+       <title></title>
+       <link></link>
+       <guid isPermaLink="true"></guid>
+       <description></description>
+       <pubDate></pubDate>
+      </item>
+     <item>
+       <title></title>
+       <link></link>
+       <guid isPermaLink="true"></guid>
+       <description></description>
+       <pubDate></pubDate>
+      </item>
+    <BLANKLINE>
+    >>> print example.item.title + example.item.title
+    <BLANKLINE>
+    >>> example.item += example.item
+    >>> print example.item
+    <item>
+       <title></title>
+       <link></link>
+       <guid isPermaLink="true"></guid>
+       <description></description>
+       <pubDate></pubDate>
+      </item>
+     <item>
+       <title></title>
+       <link></link>
+       <guid isPermaLink="true"></guid>
+       <description></description>
+       <pubDate></pubDate>
+      </item>
+    <BLANKLINE>
+    >>> example.reset()
+    >>> example.item.repeat()
+    >>> print example
+    <rss version="2.0">
+     <channel>
+      <title>Example</title>
+      <link>http://www.example.org/</link>
+      <description>RSS Example</description>
+      <language>en-us</language>
+      <pubDate> , </pubDate>
+      <lastBuildDate> , </lastBuildDate>
+      <item>
+       <title></title>
+       <link></link>
+       <guid isPermaLink="true"></guid>
+       <description></description>
+       <pubDate></pubDate>
+      </item>
+     <item>
+       <title></title>
+       <link></link>
+       <guid isPermaLink="true"></guid>
+       <description></description>
+       <pubDate></pubDate>
+      </item>
+     </channel>
+    </rss>
+    >>> example.reset()
+    >>> example.item *= 2
+    >>> print example
+    <rss version="2.0">
+     <channel>
+      <title>Example</title>
+      <link>http://www.example.org/</link>
+      <description>RSS Example</description>
+      <language>en-us</language>
+      <pubDate> , </pubDate>
+      <lastBuildDate> , </lastBuildDate>
+      <item>
+       <title></title>
+       <link></link>
+       <guid isPermaLink="true"></guid>
+       <description></description>
+       <pubDate></pubDate>
+      </item>
+     <item>
+       <title></title>
+       <link></link>
+       <guid isPermaLink="true"></guid>
+       <description></description>
+       <pubDate></pubDate>
+      </item>
+     </channel>
+    </rss>
+    >>> example.reset()
+    >>> example.item %= ('Example Title: First Example', 'http://www.example.com/rss/5423092', 'http://www.example.com/rss/5423092', 'Example of assigning text to a field.', 'June 06, 2006')
+    >>> example.item.repeat(('Example Title: Second Example', 'http://www.example.com/rss/5423093', 'http://www.example.com/rss/5423093', 'Example of group repetition.', 'June 06, 2006'))
+    >>> print example
+    <rss version="2.0">
+     <channel>
+      <title>Example</title>
+      <link>http://www.example.org/</link>
+      <description>RSS Example</description>
+      <language>en-us</language>
+      <pubDate> , </pubDate>
+      <lastBuildDate> , </lastBuildDate>
+      <item>
+       <title>Example Title: First Example</title>
+       <link>http://www.example.com/rss/5423092</link>
+       <guid isPermaLink="true">http://www.example.com/rss/5423092</guid>
+       <description>Example of assigning text to a field.</description>
+       <pubDate>June 06, 2006</pubDate>
+      </item>
+     <item>
+       <title>Example Title: Second Example</title>
+       <link>http://www.example.com/rss/5423093</link>
+       <guid isPermaLink="true">http://www.example.com/rss/5423093</guid>
+       <description>Example of group repetition.</description>
+       <pubDate>June 06, 2006</pubDate>
+      </item>
+     </channel>
+    </rss>
+    >>> example.reset()
+    >>> example.item **= (('Example Title: First Example', 'http://www.example.com/rss/5423092', 'http://www.example.com/rss/5423092', 'Example of assigning text to a field.', 'June 06, 2006'),
+    ... ('Example Title: Second Example', 'http://www.example.com/rss/5423093', 'http://www.example.com/rss/5423093', 'Example of group repetition.', 'June 06, 2006'))
+    >>> print example
+    <rss version="2.0">
+     <channel>
+      <title>Example</title>
+      <link>http://www.example.org/</link>
+      <description>RSS Example</description>
+      <language>en-us</language>
+      <pubDate> , </pubDate>
+      <lastBuildDate> , </lastBuildDate>
+      <item>
+       <title>Example Title: First Example</title>
+       <link>http://www.example.com/rss/5423092</link>
+       <guid isPermaLink="true">http://www.example.com/rss/5423092</guid>
+       <description>Example of assigning text to a field.</description>
+       <pubDate>June 06, 2006</pubDate>
+      </item>
+     <item>
+       <title>Example Title: Second Example</title>
+       <link>http://www.example.com/rss/5423093</link>
+       <guid isPermaLink="true">http://www.example.com/rss/5423093</guid>
+       <description>Example of group repetition.</description>
+       <pubDate>June 06, 2006</pubDate>
+      </item>
+     </channel>
+    </rss>
+    >>> example.cpubdate %= {'month':'June', 'day':'06', 'year':'2006'}
+    >>> example.lastbuilddate %= {'month':'June', 'day':'06', 'year':'2006'}
+    >>> print example
+    <rss version="2.0">
+     <channel>
+      <title>Example</title>
+      <link>http://www.example.org/</link>
+      <description>RSS Example</description>
+      <language>en-us</language>
+      <pubDate>June 06, 2006</pubDate>
+      <lastBuildDate>June 06, 2006</lastBuildDate>
+      <item>
+       <title>Example Title: First Example</title>
+       <link>http://www.example.com/rss/5423092</link>
+       <guid isPermaLink="true">http://www.example.com/rss/5423092</guid>
+       <description>Example of assigning text to a field.</description>
+       <pubDate>June 06, 2006</pubDate>
+      </item>
+     <item>
+       <title>Example Title: Second Example</title>
+       <link>http://www.example.com/rss/5423093</link>
+       <guid isPermaLink="true">http://www.example.com/rss/5423093</guid>
+       <description>Example of group repetition.</description>
+       <pubDate>June 06, 2006</pubDate>
+      </item>
+     </channel>
+    </rss>'''
+    import doctest
+    doctest.testmod()
+
+if __name__ == "__main__": _test()

tests/doctest_webstring.py

+# -*- coding: utf-8 -*-
+'''Doctests for webstring'''
+
+
+def _test():
+    '''
+    >>> from webstring import Template
+    >>> example = Template("""<rss version="2.0">
+    ...  <channel>
+    ...   <title>Example</title>
+    ...   <link>http://www.example.org/</link>
+    ...   <description>RSS Example</description>
+    ...   <language>en-us</language>
+    ...   <pubDate id="cpubdate">$month $day, $year</pubDate>
+    ...   <lastBuildDate id="lastbuilddate">%(month)s %(day)s, %(year)s</lastBuildDate>
+    ...   <item class="item">
+    ...    <title id="title"/>
+    ...    <link id="link"/>
+    ...    <guid isPermaLink="true" id="guid"/>
+    ...    <description id="description"/>
+    ...    <pubDate id="ipubdate"/>
+    ...   </item>
+    ...  </channel>
+    ...  </rss>""", engine="lxml")
+    >>> example.exclude('cpubdate', 'guid') 
+    >>> print example
+    <rss version="2.0">
+     <channel>
+      <title>Example</title>
+      <link>http://www.example.org/</link>
+      <description>RSS Example</description>
+      <language>en-us</language>
+      <lastBuildDate id="lastbuilddate">%(month)s %(day)s, %(year)s</lastBuildDate>
+      <item class="item">
+       <title id="title"/>
+       <link id="link"/>
+       <description id="description"/>
+       <pubDate id="ipubdate"/>
+      </item>
+     </channel>
+     </rss>
+    >>> example.include('cpubdate', 'guid') 
+    >>> print example
+    <rss version="2.0">
+     <channel>
+      <title>Example</title>
+      <link>http://www.example.org/</link>
+      <description>RSS Example</description>
+      <language>en-us</language>
+      <pubDate id="cpubdate">$month $day, $year</pubDate>
+      <lastBuildDate id="lastbuilddate">%(month)s %(day)s, %(year)s</lastBuildDate>
+      <item class="item">
+       <title id="title"/>
+       <link id="link"/>
+       <guid isPermaLink="true" id="guid"/>
+       <description id="description"/>
+       <pubDate id="ipubdate"/>
+      </item>
+     </channel>
+     </rss>
+    >>> example.cpubdate.text = {'month':'June', 'day':'06', 'year':'2006'}
+    >>> print example
+    <rss version="2.0">
+     <channel>
+      <title>Example</title>
+      <link>http://www.example.org/</link>
+      <description>RSS Example</description>
+      <language>en-us</language>
+      <pubDate id="cpubdate">June 06, 2006</pubDate>
+      <lastBuildDate id="lastbuilddate">%(month)s %(day)s, %(year)s</lastBuildDate>
+      <item class="item">
+       <title id="title"/>
+       <link id="link"/>
+       <guid isPermaLink="true" id="guid"/>
+       <description id="description"/>
+       <pubDate id="ipubdate"/>
+      </item>
+     </channel>
+     </rss>
+    >>> example.lastbuilddate.text = {'month':'June', 'day':'06', 'year':'2006'}
+    >>> print example
+    <rss version="2.0">
+     <channel>
+      <title>Example</title>
+      <link>http://www.example.org/</link>
+      <description>RSS Example</description>
+      <language>en-us</language>
+      <pubDate id="cpubdate">June 06, 2006</pubDate>
+      <lastBuildDate id="lastbuilddate">June 06, 2006</lastBuildDate>
+      <item class="item">
+       <title id="title"/>
+       <link id="link"/>
+       <guid isPermaLink="true" id="guid"/>
+       <description id="description"/>
+       <pubDate id="ipubdate"/>
+      </item>
+     </channel>
+     </rss>
+    >>> example.item.description.text = 'Example of assigning text to a field.' 
+    >>> print example
+    <rss version="2.0">
+     <channel>
+      <title>Example</title>
+      <link>http://www.example.org/</link>
+      <description>RSS Example</description>
+      <language>en-us</language>
+      <pubDate id="cpubdate">June 06, 2006</pubDate>
+      <lastBuildDate id="lastbuilddate">June 06, 2006</lastBuildDate>
+      <item class="item">
+       <title id="title"/>
+       <link id="link"/>
+       <guid isPermaLink="true" id="guid"/>
+       <description id="description">Example of assigning text to a field.</description>
+       <pubDate id="ipubdate"/>
+      </item>
+     </channel>
+     </rss>
+    >>> print example.lastbuilddate.template
+    %(month)s %(day)s, %(year)s
+    >>> example.item.link.template = 'http://www.example.com/rss/$id'
+    >>> example.item.link.text = {'id':'5423093'}
+    >>> print example
+    <rss version="2.0">
+     <channel>
+      <title>Example</title>
+      <link>http://www.example.org/</link>
+      <description>RSS Example</description>
+      <language>en-us</language>
+      <pubDate id="cpubdate">June 06, 2006</pubDate>
+      <lastBuildDate id="lastbuilddate">June 06, 2006</lastBuildDate>
+      <item class="item">
+       <title id="title"/>
+       <link id="link">http://www.example.com/rss/5423093</link>
+       <guid isPermaLink="true" id="guid"/>
+       <description id="description">Example of assigning text to a field.</description>
+       <pubDate id="ipubdate"/>
+      </item>
+     </channel>
+     </rss>
+    >>> example.item.templates({'title':{'text':'Example Title: $content'}, 'ipubdate':{'text':'$month $day, $year'}})
+    >>> example.item.title.text = {'content':'First Example'}
+    >>> example.item.ipubdate.text = {'month':'June', 'day':'6', 'year':'2006'}
+    >>> print example
+    <rss version="2.0">
+     <channel>
+      <title>Example</title>
+      <link>http://www.example.org/</link>
+      <description>RSS Example</description>
+      <language>en-us</language>
+      <pubDate id="cpubdate">June 06, 2006</pubDate>
+      <lastBuildDate id="lastbuilddate">June 06, 2006</lastBuildDate>
+      <item class="item">
+       <title id="title">Example Title: First Example</title>
+       <link id="link">http://www.example.com/rss/5423093</link>
+       <guid isPermaLink="true" id="guid"/>
+       <description id="description">Example of assigning text to a field.</description>
+       <pubDate id="ipubdate">June 6, 2006</pubDate>
+      </item>
+     </channel>
+     </rss>
+    >>> example.item.guid.update({'isPermaLink':'true', 'id':'GUID', '{http://www.w3.org/1999/02/22-rdf-syntax-ns#}resource':'http://www.example.com/rss/5423093'})
+    >>> print example
+    <rss version="2.0">
+     <channel>
+      <title>Example</title>
+      <link>http://www.example.org/</link>
+      <description>RSS Example</description>
+      <language>en-us</language>
+      <pubDate id="cpubdate">June 06, 2006</pubDate>
+      <lastBuildDate id="lastbuilddate">June 06, 2006</lastBuildDate>
+      <item class="item">
+       <title id="title">Example Title: First Example</title>
+       <link id="link">http://www.example.com/rss/5423093</link>
+       <guid xmlns:ns0="http://www.w3.org/1999/02/22-rdf-syntax-ns#" isPermaLink="true" id="GUID" ns0:resource="http://www.example.com/rss/5423093"/>
+       <description id="description">Example of assigning text to a field.</description>
+       <pubDate id="ipubdate">June 6, 2006</pubDate>
+      </item>
+     </channel>
+     </rss>
+    >>> example.item.guid.atemplates({'{http://www.w3.org/1999/02/22-rdf-syntax-ns#}resource':'http://www.example.com/rss/$guid'})
+    >>> example.item.guid.update({'{http://www.w3.org/1999/02/22-rdf-syntax-ns#}resource':{'guid':'5423094'}})
+    >>> print example
+    <rss version="2.0">
+     <channel>
+      <title>Example</title>
+      <link>http://www.example.org/</link>
+      <description>RSS Example</description>
+      <language>en-us</language>
+      <pubDate id="cpubdate">June 06, 2006</pubDate>
+      <lastBuildDate id="lastbuilddate">June 06, 2006</lastBuildDate>
+      <item class="item">
+       <title id="title">Example Title: First Example</title>
+       <link id="link">http://www.example.com/rss/5423093</link>
+       <guid xmlns:ns0="http://www.w3.org/1999/02/22-rdf-syntax-ns#" isPermaLink="true" id="GUID" ns0:resource="http://www.example.com/rss/5423094"/>
+       <description id="description">Example of assigning text to a field.</description>
+       <pubDate id="ipubdate">June 6, 2006</pubDate>
+      </item>
+     </channel>
+     </rss>
+    >>> example.item.guid.resource = {'guid':'5423093'}
+    >>> print example
+    <rss version="2.0">
+     <channel>
+      <title>Example</title>
+      <link>http://www.example.org/</link>
+      <description>RSS Example</description>
+      <language>en-us</language>
+      <pubDate id="cpubdate">June 06, 2006</pubDate>
+      <lastBuildDate id="lastbuilddate">June 06, 2006</lastBuildDate>
+      <item class="item">
+       <title id="title">Example Title: First Example</title>
+       <link id="link">http://www.example.com/rss/5423093</link>
+       <guid xmlns:ns0="http://www.w3.org/1999/02/22-rdf-syntax-ns#" isPermaLink="true" id="GUID" ns0:resource="http://www.example.com/rss/5423093"/>
+       <description id="description">Example of assigning text to a field.</description>
+       <pubDate id="ipubdate">June 6, 2006</pubDate>
+      </item>
+     </channel>
+     </rss>
+    >>> example.item.guid.purge('{http://www.w3.org/1999/02/22-rdf-syntax-ns#}resource')
+    >>> print example
+    <rss version="2.0">
+     <channel>
+      <title>Example</title>
+      <link>http://www.example.org/</link>
+      <description>RSS Example</description>
+      <language>en-us</language>
+      <pubDate id="cpubdate">June 06, 2006</pubDate>
+      <lastBuildDate id="lastbuilddate">June 06, 2006</lastBuildDate>
+      <item class="item">
+       <title id="title">Example Title: First Example</title>
+       <link id="link">http://www.example.com/rss/5423093</link>
+       <guid xmlns:ns0="http://www.w3.org/1999/02/22-rdf-syntax-ns#" isPermaLink="true" id="GUID"/>
+       <description id="description">Example of assigning text to a field.</description>
+       <pubDate id="ipubdate">June 6, 2006</pubDate>
+      </item>
+     </channel>
+     </rss>
+    >>> example.item.guid.text = 'http://www.example.com/rss/5423093'
+    >>> print example
+    <rss version="2.0">
+     <channel>
+      <title>Example</title>
+      <link>http://www.example.org/</link>
+      <description>RSS Example</description>
+      <language>en-us</language>
+      <pubDate id="cpubdate">June 06, 2006</pubDate>
+      <lastBuildDate id="lastbuilddate">June 06, 2006</lastBuildDate>
+      <item class="item">
+       <title id="title">Example Title: First Example</title>
+       <link id="link">http://www.example.com/rss/5423093</link>
+       <guid xmlns:ns0="http://www.w3.org/1999/02/22-rdf-syntax-ns#" isPermaLink="true" id="GUID">http://www.example.com/rss/5423093</guid>
+       <description id="description">Example of assigning text to a field.</description>
+       <pubDate id="ipubdate">June 6, 2006</pubDate>
+      </item>
+     </channel>
+     </rss>
+    >>> example.reset()
+    >>> print example
+    <rss version="2.0">
+     <channel>
+      <title>Example</title>
+      <link>http://www.example.org/</link>
+      <description>RSS Example</description>
+      <language>en-us</language>
+      <pubDate id="cpubdate">$month $day, $year</pubDate>
+      <lastBuildDate id="lastbuilddate">%(month)s %(day)s, %(year)s</lastBuildDate>
+      <item class="item">
+       <title id="title"/>
+       <link id="link"/>
+       <guid isPermaLink="true" id="guid"/>
+       <description id="description"/>
+       <pubDate id="ipubdate"/>
+      </item>
+     </channel>
+     </rss>
+    >>> example %= {
+    ... 'cpubdate':{'text':{'month':'June', 'day':'06', 'year':'2006'}}, 
+    ... 'lastbuilddate':{'text':{'month':'June', 'day':'06', 'year':'2006'}},
+    ... 'item':{'templates':{'title':{'text':'Example Title: $content'}, 'ipubdate':{'text':'$month $day, $year'},
+    ... 	'link':{'text':'http://www.example.com/rss/$id'}},
+    ... 	'title':{'text':{'content':'First Example'}},
+    ... 	'link':{'text':{'id':'5423093'}},
+    ... 	'guid':{'attrib':{'id':'GUID'}, 'text':'http://www.example.com/rss/5423093'},
+    ... 	'description':{'text':'Example of assigning text to a field.'},
+    ... 	'ipubdate':{'text':{'month':'June', 'day':'6', 'year':'2006'}}}}
+    >>> print example
+    <rss version="2.0">
+     <channel>
+      <title>Example</title>
+      <link>http://www.example.org/</link>
+      <description>RSS Example</description>
+      <language>en-us</language>
+      <pubDate id="cpubdate">June 06, 2006</pubDate>
+      <lastBuildDate id="lastbuilddate">June 06, 2006</lastBuildDate>
+      <item class="item">
+       <title id="title">Example Title: First Example</title>
+       <link id="link">http://www.example.com/rss/5423093</link>
+       <guid isPermaLink="true" id="GUID">http://www.example.com/rss/5423093</guid>
+       <description id="description">Example of assigning text to a field.</description>
+       <pubDate id="ipubdate">June 6, 2006</pubDate>
+      </item>
+     </channel>
+     </rss>
+    >>> example.cpubdate %= {'text':{'month':'June', 'day':'06', 'year':'2006'}}
+    >>> example.lastbuilddate %= {'text':{'month':'June', 'day':'06', 'year':'2006'}}
+    >>> example.item %= {
+    ... 'templates':{
+    ...     'title':{'text':'Example Title: $content'},
+    ...     'ipubdate':{'text':'$month $day, $year'},
+    ...     'link':{'text':'http://www.example.com/rss/$id'}},
+    ... 'subs':((
+    ...     {'text':{'content':'First Example'}},
+    ...     {'text':{'id':'5423093'}}, {'attrib':{'id':'GUID'},
+    ...     'text':'http://www.example.com/rss/5423093'},
+    ...     'Example of assigning text to a field.',
+    ...     {'text':{'month':'June', 'day':'6', 'year':'2006'}}),)}
+    >>> print example
+    <rss version="2.0">
+     <channel>
+      <title>Example</title>
+      <link>http://www.example.org/</link>
+      <description>RSS Example</description>
+      <language>en-us</language>
+      <pubDate id="cpubdate">June 06, 2006</pubDate>
+      <lastBuildDate id="lastbuilddate">June 06, 2006</lastBuildDate>
+      <item class="item">
+       <title id="title">Example Title: First Example</title>
+       <link id="link">http://www.example.com/rss/5423093</link>
+       <guid isPermaLink="true" id="GUID">http://www.example.com/rss/5423093</guid>
+       <description id="description">Example of assigning text to a field.</description>
+       <pubDate id="ipubdate">June 6, 2006</pubDate>
+      </item>
+     </channel>
+     </rss>
+    >>> print example.current
+    <rss version="2.0">
+     <channel>
+      <title>Example</title>
+      <link>http://www.example.org/</link>
+      <description>RSS Example</description>
+      <language>en-us</language>
+      <pubDate id="cpubdate">June 06, 2006</pubDate>
+      <lastBuildDate id="lastbuilddate">June 06, 2006</lastBuildDate>
+      <item class="item">
+       <title id="title">Example Title: First Example</title>
+       <link id="link">http://www.example.com/rss/5423093</link>
+       <guid isPermaLink="true" id="GUID">http://www.example.com/rss/5423093</guid>
+       <description id="description">Example of assigning text to a field.</description>
+       <pubDate id="ipubdate">June 6, 2006</pubDate>
+      </item>
+     </channel>
+     </rss>
+    >>> print example.default
+    <rss version="2.0">
+     <channel>
+      <title>Example</title>
+      <link>http://www.example.org/</link>
+      <description>RSS Example</description>
+      <language>en-us</language>
+      <pubDate id="cpubdate">$month $day, $year</pubDate>
+      <lastBuildDate id="lastbuilddate">%(month)s %(day)s, %(year)s</lastBuildDate>
+      <item class="item">
+       <title id="title"/>
+       <link id="link"/>
+       <guid isPermaLink="true" id="guid"/>
+       <description id="description"/>
+       <pubDate id="ipubdate"/>
+      </item>
+     </channel>
+     </rss>
+    >>> example.reset()
+    >>> print example + example
+    <rss version="2.0">
+     <channel>
+      <title>Example</title>
+      <link>http://www.example.org/</link>
+      <description>RSS Example</description>
+      <language>en-us</language>
+      <pubDate id="cpubdate">$month $day, $year</pubDate>
+      <lastBuildDate id="lastbuilddate">%(month)s %(day)s, %(year)s</lastBuildDate>
+      <item class="item">
+       <title id="title"/>
+       <link id="link"/>
+       <guid isPermaLink="true" id="guid"/>
+       <description id="description"/>
+       <pubDate id="ipubdate"/>
+      </item>
+     </channel>
+     <rss version="2.0">
+     <channel>
+      <title>Example</title>
+      <link>http://www.example.org/</link>
+      <description>RSS Example</description>
+      <language>en-us</language>
+      <pubDate id="cpubdate">$month $day, $year</pubDate>
+      <lastBuildDate id="lastbuilddate">%(month)s %(day)s, %(year)s</lastBuildDate>
+      <item class="item">
+       <title id="title"/>
+       <link id="link"/>
+       <guid isPermaLink="true" id="guid"/>
+       <description id="description"/>
+       <pubDate id="ipubdate"/>
+      </item>
+     </channel>
+     </rss></rss>
+    >>> print example.item + example.item
+    <item class="item">
+       <title id="title"/>
+       <link id="link"/>
+       <guid isPermaLink="true" id="guid"/>
+       <description id="description"/>
+       <pubDate id="ipubdate"/>
+      </item>
+     <item class="item">
+       <title id="title"/>
+       <link id="link"/>
+       <guid isPermaLink="true" id="guid"/>
+       <description id="description"/>
+       <pubDate id="ipubdate"/>
+      </item>
+    <BLANKLINE>
+    >>> print example.item.title + example.item.title
+    <title id="title"/>
+       <title id="title"/>
+    <BLANKLINE>
+    >>> example.item += example.item
+    >>> print example
+    <rss version="2.0">
+     <channel>
+      <title>Example</title>
+      <link>http://www.example.org/</link>
+      <description>RSS Example</description>
+      <language>en-us</language>
+      <pubDate id="cpubdate">$month $day, $year</pubDate>
+      <lastBuildDate id="lastbuilddate">%(month)s %(day)s, %(year)s</lastBuildDate>
+      <item class="item">
+       <title id="title"/>
+       <link id="link"/>
+       <guid isPermaLink="true" id="guid"/>
+       <description id="description"/>
+       <pubDate id="ipubdate"/>
+      </item>
+     <item class="item">
+       <title id="title"/>
+       <link id="link"/>
+       <guid isPermaLink="true" id="guid"/>
+       <description id="description"/>
+       <pubDate id="ipubdate"/>
+      </item>
+     </channel>
+     </rss>
+    >>> example.reset()
+    >>> example.repeat()
+    >>> print example
+    <rss version="2.0">
+     <channel>
+      <title>Example</title>
+      <link>http://www.example.org/</link>
+      <description>RSS Example</description>
+      <language>en-us</language>
+      <pubDate id="cpubdate">$month $day, $year</pubDate>
+      <lastBuildDate id="lastbuilddate">%(month)s %(day)s, %(year)s</lastBuildDate>
+      <item class="item">
+       <title id="title"/>
+       <link id="link"/>
+       <guid isPermaLink="true" id="guid"/>
+       <description id="description"/>
+       <pubDate id="ipubdate"/>
+      </item>
+     </channel>
+     <rss version="2.0">
+     <channel>
+      <title>Example</title>
+      <link>http://www.example.org/</link>
+      <description>RSS Example</description>
+      <language>en-us</language>
+      <pubDate id="cpubdate">$month $day, $year</pubDate>
+      <lastBuildDate id="lastbuilddate">%(month)s %(day)s, %(year)s</lastBuildDate>
+      <item class="item">
+       <title id="title"/>
+       <link id="link"/>
+       <guid isPermaLink="true" id="guid"/>
+       <description id="description"/>
+       <pubDate id="ipubdate"/>
+      </item>
+     </channel>
+     </rss></rss>
+    >>> example.reset()
+    >>> example.item *= 2
+    >>> print example
+    <rss version="2.0">
+     <channel>
+      <title>Example</title>
+      <link>http://www.example.org/</link>
+      <description>RSS Example</description>
+      <language>en-us</language>
+      <pubDate id="cpubdate">$month $day, $year</pubDate>
+      <lastBuildDate id="lastbuilddate">%(month)s %(day)s, %(year)s</lastBuildDate>
+      <item class="item">
+       <title id="title"/>
+       <link id="link"/>
+       <guid isPermaLink="true" id="guid"/>
+       <description id="description"/>
+       <pubDate id="ipubdate"/>
+      </item>
+     <item class="item">
+       <title id="title"/>
+       <link id="link"/>
+       <guid isPermaLink="true" id="guid"/>
+       <description id="description"/>
+       <pubDate id="ipubdate"/>
+      </item>
+     </channel>
+     </rss>
+    >>> example.reset()
+    >>> example.item %= ('Example Title: First Example', 'http://www.example.com/rss/5423092', 'http://www.example.com/rss/5423092', 'Example of assigning text to a field.', 'June 06, 2006')
+    >>> example.item.repeat(('Example Title: Second Example', 'http://www.example.com/rss/5423093', 'http://www.example.com/rss/5423093', 'Example of group repetition.', 'June 06, 2006'))
+    >>> print example
+    <rss version="2.0">
+     <channel>
+      <title>Example</title>
+      <link>http://www.example.org/</link>
+      <description>RSS Example</description>
+      <language>en-us</language>
+      <pubDate id="cpubdate">$month $day, $year</pubDate>
+      <lastBuildDate id="lastbuilddate">%(month)s %(day)s, %(year)s</lastBuildDate>
+      <item class="item">
+       <title id="title">Example Title: First Example</title>
+       <link id="link">http://www.example.com/rss/5423092</link>
+       <guid isPermaLink="true" id="guid">http://www.example.com/rss/5423092</guid>
+       <description id="description">Example of assigning text to a field.</description>
+       <pubDate id="ipubdate">June 06, 2006</pubDate>
+      </item>
+     <item class="item">
+       <title id="title">Example Title: Second Example</title>
+       <link id="link">http://www.example.com/rss/5423093</link>
+       <guid isPermaLink="true" id="guid">http://www.example.com/rss/5423093</guid>
+       <description id="description">Example of group repetition.</description>
+       <pubDate id="ipubdate">June 06, 2006</pubDate>
+      </item>
+     </channel>
+     </rss>
+    >>> example.reset()
+    >>> example.item **= (('Example Title: First Example', 'http://www.example.com/rss/5423092', 'http://www.example.com/rss/5423092', 'Example of assigning text to a field.', 'June 06, 2006'),
+    ... ('Example Title: Second Example', 'http://www.example.com/rss/5423093', 'http://www.example.com/rss/5423093', 'Example of group repetition.', 'June 06, 2006'))
+    >>> print example
+    <rss version="2.0">
+     <channel>
+      <title>Example</title>
+      <link>http://www.example.org/</link>
+      <description>RSS Example</description>
+      <language>en-us</language>
+      <pubDate id="cpubdate">$month $day, $year</pubDate>
+      <lastBuildDate id="lastbuilddate">%(month)s %(day)s, %(year)s</lastBuildDate>
+      <item class="item">
+       <title id="title">Example Title: First Example</title>
+       <link id="link">http://www.example.com/rss/5423092</link>
+       <guid isPermaLink="true" id="guid">http://www.example.com/rss/5423092</guid>
+       <description id="description">Example of assigning text to a field.</description>
+       <pubDate id="ipubdate">June 06, 2006</pubDate>
+      </item>
+     <item class="item">
+       <title id="title">Example Title: Second Example</title>
+       <link id="link">http://www.example.com/rss/5423093</link>
+       <guid isPermaLink="true" id="guid">http://www.example.com/rss/5423093</guid>
+       <description id="description">Example of group repetition.</description>
+       <pubDate id="ipubdate">June 06, 2006</pubDate>
+      </item>
+     </channel>
+     </rss>
+    >>> example.reset()
+    >>> example.item %= {'templates':{'title':{'text':'Example Title: $content'}, 'ipubdate':{'text':'$month $day, $year'}, 'link':{'text':'http://www.example.com/rss/$id'}},
+    ... 'subs':(
+    ... ({'text':{'content':'First Example'}}, {'text':{'id':'5423092'}}, 'http://www.example.com/rss/5423092', 
+    ... 'Example of assigning text to a field.', {'text':{'month':'June', 'day':'06', 'year':'2006'}}),
+    ... ({'text':{'content':'Second Example'}}, {'text':{'id':'5423093'}}, 'http://www.example.com/rss/5423093', 
+    ... 'Example of group repetition.', {'text':{'month':'June', 'day':'06', 'year':'2006'}}))}
+    >>> print example
+    <rss version="2.0">
+     <channel>
+      <title>Example</title>
+      <link>http://www.example.org/</link>
+      <description>RSS Example</description>
+      <language>en-us</language>
+      <pubDate id="cpubdate">$month $day, $year</pubDate>
+      <lastBuildDate id="lastbuilddate">%(month)s %(day)s, %(year)s</lastBuildDate>
+      <item class="item">
+       <title id="title">Example Title: First Example</title>
+       <link id="link">http://www.example.com/rss/5423092</link>
+       <guid isPermaLink="true" id="guid">http://www.example.com/rss/5423092</guid>
+       <description id="description">Example of assigning text to a field.</description>
+       <pubDate id="ipubdate">June 06, 2006</pubDate>
+      </item>
+     <item class="item">
+       <title id="title">Example Title: Second Example</title>
+       <link id="link">http://www.example.com/rss/5423093</link>
+       <guid isPermaLink="true" id="guid">http://www.example.com/rss/5423093</guid>
+       <description id="description">Example of group repetition.</description>
+       <pubDate id="ipubdate">June 06, 2006</pubDate>
+      </item>
+     </channel>
+     </rss>
+    >>> example.reset()
+    >>> example.cpubdate.text = {'month':'June', 'day':'06', 'year':'2006'}
+    >>> example.lastbuilddate.text = {'month':'June', 'day':'06', 'year':'2006'}
+    >>> example.item %= {'templates':{'title':{'text':'Example Title: $content'}, 'ipubdate':{'text':'$month $day, $year'}, 'link':{'text':'http://www.example.com/rss/$id'}},
+    ... 'subs':(
+    ... ({'text':{'content':'First Example'}}, {'text':{'id':'5423092'}}, 'http://www.example.com/rss/5423092', 
+    ... 'Example of assigning text to a field.', {'text':{'month':'June', 'day':'06', 'year':'2006'}}),
+    ... ({'text':{'content':'Second Example'}}, {'text':{'id':'5423093'}}, 'http://www.example.com/rss/5423093', 
+    ... 'Example of group repetition.', {'text':{'month':'June', 'day':'06', 'year':'2006'}}))}
+    >>> example.item.description.append(Template('<html><head><title>Example</title></head><body><p>Paragraph</p></body></html>', engine='lxml'))
+    >>> del example.item.description.text
+    >>> print example
+    <rss version="2.0">
+     <channel>
+      <title>Example</title>
+      <link>http://www.example.org/</link>
+      <description>RSS Example</description>
+      <language>en-us</language>
+      <pubDate id="cpubdate">June 06, 2006</pubDate>
+      <lastBuildDate id="lastbuilddate">June 06, 2006</lastBuildDate>
+      <item class="item">
+       <title id="title">Example Title: First Example</title>
+       <link id="link">http://www.example.com/rss/5423092</link>
+       <guid isPermaLink="true" id="guid">http://www.example.com/rss/5423092</guid>
+       <description id="description"><html><head><title>Example</title></head><body><p>Paragraph</p></body></html></description>
+       <pubDate id="ipubdate">June 06, 2006</pubDate>
+      </item>
+     <item class="item">
+       <title id="title">Example Title: Second Example</title>
+       <link id="link">http://www.example.com/rss/5423093</link>
+       <guid isPermaLink="true" id="guid">http://www.example.com/rss/5423093</guid>
+       <description id="description">Example of group repetition.</description>
+       <pubDate id="ipubdate">June 06, 2006</pubDate>
+      </item>
+     </channel>
+     </rss>
+    >>> del example.mark
+    >>> print example
+    <rss version="2.0">
+     <channel>
+      <title>Example</title>
+      <link>http://www.example.org/</link>
+      <description>RSS Example</description>
+      <language>en-us</language>
+      <pubDate>June 06, 2006</pubDate>
+      <lastBuildDate>June 06, 2006</lastBuildDate>
+      <item class="item">
+       <title>Example Title: First Example</title>
+       <link>http://www.example.com/rss/5423092</link>
+       <guid isPermaLink="true">http://www.example.com/rss/5423092</guid>
+       <description><html><head><title>Example</title></head><body><p>Paragraph</p></body></html></description>
+       <pubDate>June 06, 2006</pubDate>
+      </item>
+     <item class="item">
+       <title>Example Title: Second Example</title>
+       <link>http://www.example.com/rss/5423093</link>
+       <guid isPermaLink="true">http://www.example.com/rss/5423093</guid>
+       <description>Example of group repetition.</description>
+       <pubDate>June 06, 2006</pubDate>
+      </item>
+     </channel>
+     </rss>
+    >>> del example.groupmark
+    >>> print example
+    <rss version="2.0">
+     <channel>
+      <title>Example</title>
+      <link>http://www.example.org/</link>
+      <description>RSS Example</description>
+      <language>en-us</language>
+      <pubDate>June 06, 2006</pubDate>
+      <lastBuildDate>June 06, 2006</lastBuildDate>
+      <item>
+       <title>Example Title: First Example</title>
+       <link>http://www.example.com/rss/5423092</link>
+       <guid isPermaLink="true">http://www.example.com/rss/5423092</guid>
+       <description><html><head><title>Example</title></head><body><p>Paragraph</p></body></html></description>
+       <pubDate>June 06, 2006</pubDate>
+      </item>
+     <item>
+       <title>Example Title: Second Example</title>
+       <link>http://www.example.com/rss/5423093</link>
+       <guid isPermaLink="true">http://www.example.com/rss/5423093</guid>
+       <description>Example of group repetition.</description>
+       <pubDate>June 06, 2006</pubDate>
+      </item>
+     </channel>
+     </rss>'''
+    import doctest
+    doctest.testmod()
+
+if __name__ == "__main__": _test()

tests/test_text.py

+# -*- coding: utf-8 -*-
+'''Unit tests for webstring'''
+
+import unittest
+try:
+    import cPickle as pickle
+except ImportError:
+    import pickle
+
+from webstring import TextTemplate
+
+
+class Testwebstring(unittest.TestCase):
+
+    '''Test class for webstring text template'''
+
+    # Add tests
+    groupend = (
+        '<tr class="tr1"><td id="td1"></td><td id="td2"></td></tr>'
+        '<tr class="tr2"><td id="td1"></td><td id="td2"></td></tr>'
+    )
+    altgroupend = (
+        '<tr class="tr2"><td id="td1"></td><td id="td2"></td>'
+        '</tr><tr class="tr1"><td id="td1"></td><td id="td2"></td></tr>'
+    )
+    subgroupend = '<td id="td1" /><td id="td1" />'
+    addtest = (
+        '<html><head><title id="title"></title></head></html><html><body>'
+        '<p id="content"></p></body></html>'
+    )
+    altaddtest = (
+        '<html><body><p id="content" /></body><head>'
+        '<title id="title" /></head></html>'
+    )
+    field_add = '<p id="content" /><title id="title" />'
+    field_group_add = (
+        '<title id="title" /><tr class="tr1"><td id="td1"></td>'
+        '<td id="td2"></td></tr>'
+    )
+    root_group_add = (
+        '<html><head><title id="title"></title></head></html>'
+        '<tr class="tr1"><td id="td1"></td><td id="td2"></td></tr>'
+    )
+    root_element_add = '<html><head><title id="title" /></head><p /></html>'
+    field_element_add = '<title id="title" /><p />'
+    group_element_add = (
+        '<tr class="tr1"><td id="td1" /><td id="td2" /></tr><p />'
+    )
+    subfield_element_add = '<td id="td1" /><p />'
+    # Mul tests
+    multest = '<p id="content" /><p id="content" /><p id="content" />'
+    root_mul = (
+        '<html><head><title id="title"></title></head><html><body>'
+        '<p id="content"></p></body></html></html><html><head><title '
+        'id="title"></title></head><html><body><p id="content"></p></body>'
+        '</html></html><html><head><title id="title"></title></head><html>'
+        '<body><p id="content"></p></body></html></html>'
+    )
+    root_group_mul = (
+        '<tr class="tr1"><td id="td1"></td><td id="td2"></td>'
+        '</tr><tr class="tr1"><td id="td1"></td><td id="td2"></td></tr>'
+        '<tr class="tr1"><td id="td1"></td><td id="td2"></td></tr>'
+    )
+    subfield_group_mul = '<td id="td1" /><td id="td1" /><td id="td1" />'
+    # Mod tests
+    modtest1 = (
+        '<html><head><title id="title">Test Page</title>'
+        '</head><body /></html>'
+    )
+    modtest2 = (
+        '<html><head><title id="title">Test Page</title></head><html><body>'
+        '<p id="content">Content Goes Here</p></body></html></html>'
+    )
+    modtest3 = (
+        '<html><head><title id="title">Title</title></head><body><p '
+        'id="content">Test1Test2</p><p id="content2">Test1Test2</p></body>'
+        '</html>'
+    )
+    modtest5 = '<title id="title">Test Page</title>'
+    groupmod = '<td id="td1">Test Page</td>'
+    groupmod2 = (
+        '<table><tr class="tr1"><td id="td1">Test Page</td>'
+        '<td id="td2">Content Goes Here</td></tr></table>'
+    )
+    groupmod3 = (
+        '<table><tr class="tr1"><td id="td1">Test1Test2</td>'
+        '<td id="td2">Test1Test2</td></tr></table>'
+    )
+    # Pow tets
+    powtest1 = '<p id="content">Test1</p><p id="content">Test2</p>'
+    groupow = (
+        '<tr class="tr1"><td id="td1">1</td>'
+        '<td id="td2">2</td></tr><tr class="tr1"><td id="td1">3' \
+        '</td><td id="td2">4</td></tr><tr class="tr1"><td id="td1">5'
+        '</td><td id="td2">6</td></tr>'
+    )
+    # Templates
+    modtemplate1 = TextTemplate(
+        '<html><head><title id="title">$title$</title></head>'
+        '<body /></html>'
+    )
+    modtemplate3 = TextTemplate(
+        '<html><head><title id="title">$title$</title></head><body><p '
+        'id="content">$content$</p><p id="content2">$content2$</p></body>'
+        '</html>'
+    )
+    gentemplate = TextTemplate(
+        '<html><head><title id="title">$title$</title></head><html><body>'
+        '<p id="content">$content$</p></body></html></html>'
+    )
+    atemplate = TextTemplate(
+        '<html><head><title id="title">$title$</title></head></html>'
+    )
+    btemplate = TextTemplate(
+        '<html><body><p id="content">$content$</p></body></html>'
+    )
+    powtemplate = TextTemplate(
+        '<html><head /><body><p id="content">$content$</p></body></html>'
+    )
+    agrouptest = TextTemplate(
+        '<table>$$tr1<tr class="tr1"><td id="td1">$td1$'
+        '</td><td id="td2">$td2$</td></tr>$$</table>'
+    )
+    bgrouptest = TextTemplate(
+        '<table>$$tr2<tr class="tr2"><td id="td1">$td1$'
+        '</td><td id="td2">$td2$</td></tr>$$</table>'
+    )
+    subcombotest = TextTemplate(
+        '<body><a id="fieldtest" href="atest">'
+        '$fieldtest$</a>$$grouptest<tr class="grouptest"><td id="groupfield1">'
+        '$groupfield1$</td><td id="groupfield2">$groupfield2$</td></tr>$$'
+        '</body>'
+    )
+    # Data structures
+    powdict = {'content1': 'Test1', 'content2': 'Test2'}
+    powtup = ('<p id="content">Test1</p>', '<p id="content">Test2</p>')
+    moddict = {'content': 'Content Goes Here', 'title': 'Test Page'}
+    groupdict = {'td1': 'Test Page', 'td2': 'Content Goes Here'}
+    modtup = ('Test Page', 'Content Goes Here')
+    grouptup = (('1', '2'), ('3', '4'), ('5', '6'))
+    groupowdict = {'2': ['1', '2'], '4': ['3', '4'], '6': ['5', '6']}
+
+    def test_root_add(self):
+        '''Tests addition of two root Templates.'''
+        atst = self.atemplate + self.btemplate
+        self.assertEqual(self.addtest, atst.render())
+
+    def test_root_radd(self):
+        '''Tests the right-side addition of two root Templates.'''
+        final = '<html><body><p id="content"></p></body></html><html>' \
+            '<head><title id="title"></title></head></html>'
+        atst = self.btemplate + self.atemplate
+        self.assertEqual(final, atst.render())
+
+    def test_root_iadd(self):
+        '''Tests the modifying addition of two root Templates.'''
+        self.atemplate += self.btemplate
+        self.assertEqual(self.addtest, self.atemplate.pipe())
+
+    def test_field_add(self):
+        '''Tests the addition of two fields.'''
+        final = '<title id="title" /><p id="content" />'
+        self.atemplate.title %= '<title id="title" />'
+        self.btemplate.content %= '<p id="content" />'
+        atst = self.atemplate.title + self.btemplate.content
+        self.assertEqual(final, atst.render())
+
+    def test_field_radd(self):
+        '''Tests the right-side addition of two fields.'''
+        self.atemplate.title %= '<title id="title" />'
+        self.btemplate.content %= '<p id="content" />'
+        atst = self.btemplate.content + self.atemplate.title
+        self.assertEqual(self.field_add, atst.render())
+
+    def test_field_iadd(self):
+        '''Tests the modifying addition of two fields.'''
+        self.atemplate.title %= '<title id="title" />'
+        self.btemplate.content += self.atemplate.title
+        self.assertEqual(self.field_add, self.btemplate.content.pipe())
+
+    def test_group_add(self):
+        '''Tests the addition of two groups.'''
+        self.agrouptest.reset()
+        atst = self.agrouptest.tr1 + self.bgrouptest.tr2
+        self.assertEqual(self.groupend, atst.render())
+
+    def test_group_radd(self):
+        '''Tests the right-side addition of two groups.'''
+        atst = self.bgrouptest.tr2 + self.agrouptest.tr1
+        self.assertEqual(self.altgroupend, atst.render())
+
+    def test_group_iadd(self):
+        '''Tests the modifying addition of two groups.'''
+        self.agrouptest.tr1 += self.bgrouptest.tr2
+        self.assertEqual(self.groupend, self.agrouptest.tr1.pipe())
+
+    def test_subfield_add(self):
+        '''Tests the addition of two subfields.'''
+        self.bgrouptest.tr2.td1 %= '<td id="td1" />'
+        self.agrouptest.tr1.td1 %= '<td id="td1" />'
+        atst = self.agrouptest.tr1.td1 + self.bgrouptest.tr2.td1
+        self.assertEqual(self.subgroupend, atst.render())
+
+    def test_subfield_radd(self):
+        '''Tests the right-side addition of two subfields.'''
+        final = '<td id="td1" /><td id="td1" />'
+        self.bgrouptest.tr2.td1 %= '<td id="td1" />'
+        self.agrouptest.tr1.td1 %= '<td id="td1" />'
+        atst = self.bgrouptest.tr2.td1 + self.agrouptest.tr1.td1
+        self.assertEqual(final, atst.render())
+
+    def test_subfield_iadd(self):
+        '''Tests the modifying addition of two subfields.'''
+        self.agrouptest.tr1.td1 %= '<td id="td1" />'
+        self.bgrouptest.tr2.td1 %= '<td id="td1" />'
+        self.agrouptest.tr1.td1 += self.bgrouptest.tr2.td1
+        self.assertEqual(self.subgroupend, self.agrouptest.tr1.td1.pipe())
+
+    def test_field_root_iadd(self):
+        '''Tests the modifying addition of a field and a root TextTemplate.'''
+        final = (
+            '<title id="title" /><html><body><p id="content"></p></body>'
+            '</html>'
+        )
+        self.atemplate.title += self.btemplate
+        self.assertEqual(final, self.atemplate.title.pipe())
+
+    def test_field_group_iadd(self):
+        '''Tests the modifying addition of a field and group.'''
+        self.atemplate.title %= '<title id="title" />'
+        self.atemplate.title += self.agrouptest.tr1
+        self.assertEqual(self.field_group_add,
+            self.atemplate.title.pipe())
+
+    def test_field_subfield_iadd(self):
+        '''Tests the modifying addition of a field and subfield.'''
+        final = '<title id="title" /><td id="td1" />'
+        self.atemplate.title %= '<title id="title" />'
+        self.agrouptest.tr1.td1 %= '<td id="td1" />'
+        self.atemplate.title += self.agrouptest.tr1.td1
+        self.assertEqual(final, self.atemplate.title.pipe())
+
+    def test_root_field_iadd(self):
+        '''Tests the modifying addition of a root TextTemplate and a field.'''
+        final = (
+            '<html><body><p id="content"></p></body></html>'
+            '<title id="title" />'
+        )
+        self.atemplate.title %= '<title id="title" />'
+        self.btemplate += self.atemplate.title
+        self.assertEqual(final, self.btemplate.pipe())
+
+    def test_root_group_iadd(self):
+        '''Tests the modifying addition of a root TextTemplate and a group.'''
+        self.atemplate.reset()
+        self.agrouptest.reset()
+        self.atemplate += self.agrouptest.tr1
+        self.assertEqual(self.root_group_add, self.atemplate.pipe())
+
+    def test_root_subfield_iadd(self):
+        '''Tests the modifying addition of a root TextTemplate and subfield.'''
+        final = (
+            '<html><head><title id="title"></title></head></html>'
+            '<td id="td1" />'
+        )
+        self.agrouptest.tr1.td1 %= '<td id="td1" />'
+        self.atemplate += self.agrouptest.tr1.td1
+        self.assertEqual(final, self.atemplate.pipe())
+
+    def test_group_subfield_iadd(self):
+        '''Tests the modifying addition of one group and one subfield.'''
+        final = (
+            '<tr class="tr1"><td id="td1"></td><td id="td2"></td>'
+            '</tr><td id="td1"></td>'
+        )
+        self.bgrouptest.tr2.td1 %= '<td id="td1"></td>'
+        self.agrouptest.tr1 += self.bgrouptest.tr2.td1
+        self.assertEqual(final, self.agrouptest.tr1.pipe())
+
+    def test_subfield_group_iadd(self):
+        '''Tests the modifying addition of one subfield and one group.'''
+        final = (
+            '<td id="td1" /><tr class="tr1"><td id="td1"></td><td id="td2">'
+            '</td></tr>'
+        )
+        self.bgrouptest.tr2.td1 += self.agrouptest.tr1
+        self.assertEqual(final, self.bgrouptest.tr2.td1.pipe())
+
+    def test_root_radd_raise(self):
+        '''
+        Raises TypeError if wrong type right-side added to root TextTemplate.
+        '''
+        def tempfunc():
+            return [1, 1, 1] + self.atemplate
+        self.assertRaises(TypeError, tempfunc)
+
+    def test_root_iadd_raise(self):
+        '''Raises TypeError if wrong type is added to root TextTemplate.'''
+        def tempfunc():
+            atst = self.atemplate.default
+            atst += [1, 1, 1]
+        self.assertRaises(TypeError, tempfunc)
+
+    def test_field_radd_raise(self):
+        '''Raises TypeError if wrong type is right-side added to field.'''
+        def tempfunc():
+            return [1, 1, 1] + self.atemplate.title
+        self.assertRaises(TypeError, tempfunc)
+
+    def test_field_iadd_raise(self):
+        '''Raises TypeError if wrong type is modifyingly added to field.'''
+        def tempfunc():
+            atst = self.atemplate.default
+            atst.title += [1, 1, 1]
+        self.assertRaises(TypeError, tempfunc)
+
+    def test_group_radd_raise(self):
+        '''Raises TypeError if wrong type is right-side added to group.'''
+        def tempfunc():
+            return [1, 1, 1] + self.agrouptest.tr1
+        self.assertRaises(TypeError, tempfunc)
+
+    def test_group_iadd_raise(self):
+        '''Raises TypeError if wrong type is modifyingly added to group.'''
+        def tempfunc():
+            atst = self.agrouptest.default
+            atst.tr1 += [1, 1, 1]
+        self.assertRaises(TypeError, tempfunc)
+
+    def test_subfield_radd_raise(self):
+        '''Raises TypeError if wrong type is right-side added to subfield.'''
+        def tempfunc():
+            return [1, 1, 1] + self.agrouptest.tr1.td1
+        self.assertRaises(TypeError, tempfunc)
+
+    def test_subfield_iadd_raise(self):
+        '''Raises TypeError if wrong type is modifyingly added to subfield.'''
+        def tempfunc():
+            atst = self.agrouptest.default
+            atst.tr1.td1 += [1, 1, 1]
+        self.assertRaises(TypeError, tempfunc)
+
+    def test_root_rmul(self):
+        '''Tests repetition of a root TextTemplate with number on the right.'''
+        atst = 3 * self.gentemplate
+        self.assertEqual(self.root_mul, atst.render())
+
+    def test_root_imul(self):
+        '''Tests modifying repetition of a root TextTemplate.'''
+        self.gentemplate *= 3
+        self.assertEqual(self.root_mul, self.gentemplate.pipe())
+
+    def test_field_mul(self):
+        '''Tests the repetition of a field.'''
+        self.gentemplate.content %= '<p id="content" />'
+        atst = self.gentemplate.content * 3
+        self.assertEqual(self.multest, atst.render())
+
+    def test_field_rmul(self):
+        '''Tests repetition of a field with the number on the right.'''
+        self.gentemplate.content %= '<p id="content" />'
+        atst = 3 * self.gentemplate.content
+        self.assertEqual(self.multest, atst.render())
+
+    def test_field_imul(self):
+        '''Tests modifying repetition of a field.'''
+        self.gentemplate.content %= '<p id="content" />'
+        self.gentemplate.content *= 3
+        self.assertEqual(self.multest, self.gentemplate.content.pipe())
+
+    def test_group_rmul(self):
+        '''Tests repetition of a group with the number on the right side.'''
+        atst = 3 * self.agrouptest.tr1
+        self.assertEqual(self.root_group_mul, atst.render())
+
+    def test_group_imul(self):
+        '''Tests modifying repetition of a group.'''
+        self.agrouptest.tr1 *= 3
+        self.assertEqual(self.root_group_mul, self.agrouptest.tr1.pipe())
+
+    def test_subfield_rmul(self):
+        '''Tests repetition of a subfield with the number on the right side.'''
+        self.agrouptest.tr1.td1 %= '<td id="td1" />'
+        atst = 3 * self.agrouptest.tr1.td1
+        self.assertEqual(self.subfield_group_mul, atst.render())
+
+    def test_subfield_mul(self):
+        '''Tests the repetition of a subfield.'''
+        self.agrouptest.tr1.td1 %= '<td id="td1" />'
+        atst = self.agrouptest.tr1.td1 * 3
+        self.assertEqual(self.subfield_group_mul, atst.render())
+
+    def test_subfield_imul(self):
+        '''Tests modifying repetition of a subfield.'''
+        self.agrouptest.tr1.td1 %= '<td id="td1" />'
+        self.agrouptest.tr1.td1 *= 3
+        self.assertEqual(self.subfield_group_mul,
+            self.agrouptest.tr1.td1.pipe())
+
+    def test_field_imul_rep(self):
+        '''Tests restraint on a max modifying repetition of a field.'''
+        def tempfunc():
+            atst = self.gentemplate.default
+            atst.content.max = 2
+            atst.content *= 3
+        self.assertRaises(TypeError, tempfunc)
+
+    def test_root_imul_rep(self):
+        '''
+        Tests restraint on max modifying repetition of a root TextTemplate.
+        '''
+        def tempfunc():
+            atst = self.gentemplate.default
+            atst.max = 2
+            atst *= 3
+        self.assertRaises(TypeError, tempfunc)
+
+    def test_group_imul_rep(self):
+        '''Tests restraint on max modifying repetition of a field.'''
+        def tempfunc():
+            atst = self.agrouptest.default
+            atst.tr1.max = 2
+            atst.tr1 *= 3
+        self.assertRaises(TypeError, tempfunc)
+
+    def test_subfield_imul_rep(self):
+        '''Tests restraint on max modifying repetition of a subfield.'''
+        def tempfunc():
+            atst = self.agrouptest.default
+            atst.tr1.td1.max = 2
+            atst.tr1.td1 *= 3
+        self.assertRaises(TypeError, tempfunc)
+
+    def test_field_string_mod(self):
+        '''Tests a modifying string substitution of a field.'''
+        atst = self.modtemplate1.title % '<title id="title">Test Page</title>'
+        self.assertEqual(atst.render(), self.modtest5)
+
+    def test_field_string_imod(self):
+        '''Tests a modifying string substitution of a field.'''
+        self.modtemplate1.title %= '<title id="title">Test Page</title>'
+        self.assertEqual(self.modtest5, self.modtemplate1.title.pipe())
+
+    def test_subfield_string_imod(self):
+        '''Tests a modifying string substitution of a subfield.'''
+        self.agrouptest.tr1.td1 %= '<td id="td1">Test Page</td>'
+        self.assertEqual(self.groupmod, self.agrouptest.tr1.td1.pipe())
+
+    def test_root_string_mod(self):
+        '''Raises TypeError if string passed to a root TextTemplate.'''
+        def tempfunc():
+            return self.gentemplate % 'Test Page'
+        self.assertRaises(TypeError, tempfunc)
+
+    def test_field_mod_str_wrongtype(self):
+        '''Raises TypeError if wrong type passed to a field.'''
+        def tempfunc():
+            return self.gentemplate.content % ['Test Page']
+        self.assertRaises(TypeError, tempfunc)
+
+    def test_root_group_str_mod_toofew(self):
+        '''Raises TypeError if string passed to root containing only group.'''
+        def tempfunc():
+            return self.agrouptest % 'Test Page'
+        self.assertRaises(TypeError, tempfunc)
+
+    def test_field_group_str_mod_toofew(self):
+        '''Raises TypeError if string passed to a group.'''
+        def tempfunc():
+            return self.agrouptest.tr1 % 'Test Page'
+        self.assertRaises(TypeError, tempfunc)
+
+    def test_root_tuple_imod(self):
+        '''Tests a modifying tuple substitution of a root TextTemplate.'''
+        self.gentemplate %= self.modtup
+        self.assertEqual(self.modtest2, self.gentemplate.pipe())
+
+    def test_group_tuple_imod(self):
+        '''Tests a modifying tuple substitution of a group.'''
+        self.agrouptest.tr1 %= self.modtup
+        self.assertEqual(self.groupmod2, self.agrouptest.pipe())
+
+    def test_root_tuple_tuple_imod_expand(self):
+        '''Tests a modifying tuple tuple substitution/expansion of root.'''
+        self.modtemplate3 %= ('Title', ('Test1', 'Test2'),
+            ('Test1', 'Test2'))
+        self.assertEqual(self.modtest3, self.modtemplate3.pipe())
+
+    def test_group_tuple_tuple_imod_expand(self):
+        '''Tests a modifying tuple tuple substitution/expansion of a group.'''
+        self.agrouptest.tr1 %= (('Test1', 'Test2'), ('Test1', 'Test2'))
+        self.assertEqual(self.groupmod3, self.agrouptest.pipe())
+
+    def test_root_tuple_mod_wrongtype(self):
+        '''Raises TypeError if wrong type in tuple is subbed into root.'''
+        def tempfunc():
+            return self.gentemplate % (set(['Test Page']),)
+        self.assertRaises(TypeError, tempfunc)
+
+    def test_group_tuple_mod_wrongtype(self):
+        '''Raises TypeError if wrong type in tuple is subbed into group.'''
+        def tempfunc():
+            return self.agrouptest.tr1 % (set(['Test Page']),)
+        self.assertRaises(TypeError, tempfunc)
+
+    def test_root_tuple_mod_toomany(self):
+        '''Raises TypeError if too many items in tuple are subbed in root.'''
+        def tempfunc():
+            return self.gentemplate % ('Test', 'Test', 'Too Many')
+        self.assertRaises(TypeError, tempfunc)
+
+    def test_group_tuple_mod_toomany(self):
+        '''Raises TypeError if too many items in tuple are subbed in group.'''
+        def tempfunc():
+            return self.agrouptest.tr1 % ('Test', 'Test', 'Test')
+        self.assertRaises(TypeError, tempfunc)
+
+    def test_root_tuple_mod_toofew(self):
+        '''Raises TypeError if too few items in tuple are subbed into root.'''
+        def tempfunc():
+            return self.gentemplate % ('Test Page')
+        self.assertRaises(TypeError, tempfunc)
+
+    def test_group_tuple_mod_toofew(self):
+        '''Raises TypeError if too few items in tuple are subbed into group.'''
+        def tempfunc():
+            return self.agrouptest.tr1 % ('Test Page')
+        self.assertRaises(TypeError, tempfunc)
+
+    def test_root_dict_imod(self):
+        '''Tests a modifying dictionary substitution of a root TextTemplate.'''
+        self.gentemplate %= self.moddict
+        self.assertEqual(self.modtest2, self.gentemplate.pipe())
+
+    def test_group_dict_imod(self):
+        '''Tests a modifying dict substitution of a group TextTemplate.'''
+        self.agrouptest.tr1 %= self.groupdict
+        self.assertEqual(self.groupmod2, self.agrouptest.pipe())
+
+    def test_root_dict_tuple_imod_expand(self):
+        '''Tests a modifying dictionary tuple sub/expansion of a root.'''
+        self.modtemplate3 %= {
+            'title': 'Title',
+            'content': ('Test1', 'Test2'),
+            "content2": ('Test1', 'Test2')
+        }
+        self.assertEqual(self.modtest3, self.modtemplate3.pipe())
+
+    def test_group_dict_tuple_imod_expand(self):
+        '''Tests a modifying dict tuple substitution/expansion of a group.'''
+        self.agrouptest.tr1 %= {
+            'td1': ('Test1', 'Test2'),
+            'td2': ('Test1', 'Test2'),
+        }
+        self.assertEqual(self.groupmod3, self.agrouptest.pipe())
+
+    def test_root_dict_mod_wrongtype(self):
+        '''Raises TypeError if wrong type in a dict are subbed into a root.'''
+        def tempfunc():
+            return self.gentemplate % {'content': set(['Test'])}
+        self.assertRaises(TypeError, tempfunc)
+
+    def test_group_dict_mod_wrongtype(self):
+        '''Raises TypeError if wrong type in a dict are subbed into a group.'''
+        def tempfunc():
+            return self.agrouptest.tr1 % {'td1': set(['Test Page'])}
+        self.assertRaises(TypeError, tempfunc)
+
+    def test_root_dict_mod_toomany(self):
+        '''Raises TypeError if too many items in dict are subbed into root.'''
+        def tempfunc():
+            return self.gentemplate % {
+                'content': 'Content Goes Here',
+                'title': 'Test Page',
+                'test': 'Too many',
+            }
+        self.assertRaises(TypeError, tempfunc)
+
+    def test_group_dict_mod_toomany(self):
+        '''Raises TypeError if too many items in dict are subbed into group.'''
+        def tempfunc():
+            return self.agrouptest.tr1 % {
+                'td1': 'Content Goes Here',
+                'td2': 'Test Page',
+                'td3': 'Too many'
+            }
+        self.assertRaises(TypeError, tempfunc)
+
+    def test_root_dict_mod_toofew(self):
+        '''Raises TypeError if too few items in dict are subbed into root.'''
+        def tempfunc():
+            return self.gentemplate % {'content': 'Content'}
+        self.assertRaises(TypeError, tempfunc)
+
+    def test_group_dict_mod_toofew(self):
+        '''Raises TypeError if too few items in dict are subbed into group.'''
+        def tempfunc():
+            return self.gentemplate % {'content': 'Content'}
+        self.assertRaises(TypeError, tempfunc)
+
+    def test_field_pow(self):
+        '''Tests a expansion of a field.'''
+        atst = self.powtemplate.content ** self.powtup
+        self.assertEqual(self.powtest1, atst.render())
+
+    def test_field_ipow(self):
+        '''Tests a modifying expansion of a field.'''
+        self.powtemplate.content **= self.powtup
+        self.assertEqual(self.powtest1, self.powtemplate.content.pipe())
+
+    def test_group_ipow(self):
+        '''Tests a modifying expansion of a group.'''
+        self.agrouptest.tr1 **= self.grouptup
+        self.assertEqual(self.groupow, self.agrouptest.tr1.pipe())
+
+    def test_field_pow_rep(self):
+        '''Raises TypeError if field expansion exceeds max repetitions.'''
+        def tempfunc():
+            atst = self.powtemplate.default
+            atst.content.max = 1
+            atst.content ** self.powtup
+        self.assertRaises(TypeError, tempfunc)