Commits

Lynn Rees  committed 27faef2

- cleanup

  • Participants
  • Parent commits 93e20d0

Comments (0)

Files changed (43)

+Changes in 0.5 include:
+
+- templating support for non-XML text formats
+- the ability to use lxml as the XML processing library for XML templates
+- the inclusion of a TurboGears/Buffet compatible template plug-in
+- xinclude support (using lxml as the XML processing library)
+- can apply XSLT stylesheets to any part of an XML template using the transform method (using lxml as the XML processing library)
+- the replication operator (*) now repeats the current state of a template instead of the default state
+- the order in which XML elements are concatenated (+) with other XML elements is now preserved 
+- decorators for WSGI templating middleware
+- cElementTree and lxml-based XML templates are properly pickled
-Copyright (c) 2006 L. C. Rees.  All rights reserved.
+Copyright (c) 2006-2012 L. C. Rees.  All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are met:
+LICENSE.txt
+MANIFEST.in
+README.rst
+requirements.txt
+setup.cfg
+setup.py
+knife/__init__.py
+knife/_active.py
+knife/_base.py
+knife/_compat.py
+knife/_kbase.py
+knife/_kmixins.py
+knife/_lazy.py
+knife/_mixins.py
+knife/active.py
+knife/base.py
+knife/lazy.py
+knife/mixins.py
+knife/tests/__init__.py
+knife/tests/mixins.py
+knife/tests/test_active.py
+knife/tests/test_lazy.py
+include LICENSE.txt
+include MANIFEST.in
+include README.rst
+include requirements.txt
+include setup.cfg
+recursive-include webstring *.py

File README

-webstring is a template engine where Python is the template language.
-
-webstring's CheeseShop page is:
-
-http://cheeseshop.python.org/pypi/webstring/
-
-More information on webstring, including documentation and an introductory tutorial, can be found at:
-
-http://psilib.sourceforge.net/webstring.html
-
-Major changes in 0.5 include:
-
-- templating support for non-XML text formats
-- the ability to use lxml as the XML processing library for XML templates
-- the inclusion of a TurboGears/Buffet compatible template plug-in
-- xinclude support (using lxml as the XML processing library)
-- can apply XSLT stylesheets to any part of an XML template using the transform method (using lxml as the XML processing library)
-- the replication operator (*) now repeats the current state of a template instead of the default state
-- the order in which XML elements are concatenated (+) with other XML elements is now preserved 
-- decorators for WSGI templating middleware
-- cElementTree and lxml-based XML templates are properly pickled
+webstring is a template engine where Python is the template language.
+
+webstring's CheeseShop page is:
+
+http://cheeseshop.python.org/pypi/webstring/
+
+More information on webstring, including documentation and an introductory tutorial, can be found at:
+
+http://psilib.sourceforge.net/webstring.html
+
+Major changes in 0.5 include:
+
+- templating support for non-XML text formats
+- the ability to use lxml as the XML processing library for XML templates
+- the inclusion of a TurboGears/Buffet compatible template plug-in
+- xinclude support (using lxml as the XML processing library)
+- can apply XSLT stylesheets to any part of an XML template using the transform method (using lxml as the XML processing library)
+- the replication operator (*) now repeats the current state of a template instead of the default state
+- the order in which XML elements are concatenated (+) with other XML elements is now preserved 

File docs/Makefile

+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS    =
+SPHINXBUILD   = sphinx-build
+PAPER         =
+BUILDDIR      = _build
+
+# Internal variables.
+PAPEROPT_a4     = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+# the i18n builder cannot share the environment and doctrees with the others
+I18NSPHINXOPTS  = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+
+.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
+
+help:
+	@echo "Please use \`make <target>' where <target> is one of"
+	@echo "  html       to make standalone HTML files"
+	@echo "  dirhtml    to make HTML files named index.html in directories"
+	@echo "  singlehtml to make a single large HTML file"
+	@echo "  pickle     to make pickle files"
+	@echo "  json       to make JSON files"
+	@echo "  htmlhelp   to make HTML files and a HTML help project"
+	@echo "  qthelp     to make HTML files and a qthelp project"
+	@echo "  devhelp    to make HTML files and a Devhelp project"
+	@echo "  epub       to make an epub"
+	@echo "  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+	@echo "  latexpdf   to make LaTeX files and run them through pdflatex"
+	@echo "  text       to make text files"
+	@echo "  man        to make manual pages"
+	@echo "  texinfo    to make Texinfo files"
+	@echo "  info       to make Texinfo files and run them through makeinfo"
+	@echo "  gettext    to make PO message catalogs"
+	@echo "  changes    to make an overview of all changed/added/deprecated items"
+	@echo "  linkcheck  to check all external links for integrity"
+	@echo "  doctest    to run all doctests embedded in the documentation (if enabled)"
+
+clean:
+	-rm -rf $(BUILDDIR)/*
+
+html:
+	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+	@echo
+	@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+dirhtml:
+	$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+	@echo
+	@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+singlehtml:
+	$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
+	@echo
+	@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
+
+pickle:
+	$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+	@echo
+	@echo "Build finished; now you can process the pickle files."
+
+json:
+	$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+	@echo
+	@echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+	$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+	@echo
+	@echo "Build finished; now you can run HTML Help Workshop with the" \
+	      ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+qthelp:
+	$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+	@echo
+	@echo "Build finished; now you can run "qcollectiongenerator" with the" \
+	      ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+	@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/webstring.qhcp"
+	@echo "To view the help file:"
+	@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/webstring.qhc"
+
+devhelp:
+	$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
+	@echo
+	@echo "Build finished."
+	@echo "To view the help file:"
+	@echo "# mkdir -p $$HOME/.local/share/devhelp/webstring"
+	@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/webstring"
+	@echo "# devhelp"
+
+epub:
+	$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
+	@echo
+	@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
+
+latex:
+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+	@echo
+	@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+	@echo "Run \`make' in that directory to run these through (pdf)latex" \
+	      "(use \`make latexpdf' here to do that automatically)."
+
+latexpdf:
+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+	@echo "Running LaTeX files through pdflatex..."
+	$(MAKE) -C $(BUILDDIR)/latex all-pdf
+	@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+text:
+	$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
+	@echo
+	@echo "Build finished. The text files are in $(BUILDDIR)/text."
+
+man:
+	$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
+	@echo
+	@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
+
+texinfo:
+	$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+	@echo
+	@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
+	@echo "Run \`make' in that directory to run these through makeinfo" \
+	      "(use \`make info' here to do that automatically)."
+
+info:
+	$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+	@echo "Running Texinfo files through makeinfo..."
+	make -C $(BUILDDIR)/texinfo info
+	@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
+
+gettext:
+	$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
+	@echo
+	@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
+
+changes:
+	$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+	@echo
+	@echo "The overview file is in $(BUILDDIR)/changes."
+
+linkcheck:
+	$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+	@echo
+	@echo "Link check complete; look for any errors in the above output " \
+	      "or in $(BUILDDIR)/linkcheck/output.txt."
+
+doctest:
+	$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
+	@echo "Testing of doctests in the sources finished, look at the " \
+	      "results in $(BUILDDIR)/doctest/output.txt."

File docs/conf.py

+# -*- coding: utf-8 -*-
+#
+# webstring documentation build configuration file, created by
+# sphinx-quickstart on Wed Apr 25 17:07:05 2012.
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys, os
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#sys.path.insert(0, os.path.abspath('.'))
+
+# -- General configuration -----------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.coverage']
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'webstring'
+copyright = u'2012, L. C. Rees'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = '0.6'
+# The full version, including alpha/beta/rc tags.
+release = '0'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = ['_build']
+
+# The reST default role (used for this markup: `text`) to use for all documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+
+# -- Options for HTML output ---------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages.  See the documentation for
+# a list of builtin themes.
+html_theme = 'default'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further.  For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = []
+
+# The name for this set of Sphinx documents.  If None, it defaults to
+# "<project> v<release> documentation".
+#html_title = None
+
+# A shorter title for the navigation bar.  Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_domain_indices = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+#html_show_sphinx = True
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+#html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it.  The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = None
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'webstringdoc'
+
+
+# -- Options for LaTeX output --------------------------------------------------
+
+latex_elements = {
+# The paper size ('letterpaper' or 'a4paper').
+#'papersize': 'letterpaper',
+
+# The font size ('10pt', '11pt' or '12pt').
+#'pointsize': '10pt',
+
+# Additional stuff for the LaTeX preamble.
+#'preamble': '',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, documentclass [howto/manual]).
+latex_documents = [
+  ('index', 'webstring.tex', u'webstring Documentation',
+   u'L. C. Rees', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# If true, show page references after internal links.
+#latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+#latex_show_urls = False
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_domain_indices = True
+
+
+# -- Options for manual page output --------------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+    ('index', 'webstring', u'webstring Documentation',
+     [u'L. C. Rees'], 1)
+]
+
+# If true, show URL addresses after external links.
+#man_show_urls = False
+
+
+# -- Options for Texinfo output ------------------------------------------------
+
+# Grouping the document tree into Texinfo files. List of tuples
+# (source start file, target name, title, author,
+#  dir menu entry, description, category)
+texinfo_documents = [
+  ('index', 'webstring', u'webstring Documentation',
+   u'L. C. Rees', 'webstring', 'One line description of project.',
+   'Miscellaneous'),
+]
+
+# Documents to append as an appendix to all manuals.
+#texinfo_appendices = []
+
+# If false, no module index is generated.
+#texinfo_domain_indices = True
+
+# How to display URL addresses: 'footnote', 'no', or 'inline'.
+#texinfo_show_urls = 'footnote'

File docs/index.rst

+.. webstring documentation master file, created by
+   sphinx-quickstart on Wed Apr 25 17:07:05 2012.
+   You can adapt this file completely to your liking, but it should at least
+   contain the root `toctree` directive.
+
+Welcome to webstring's documentation!
+=====================================
+
+Contents:
+
+.. toctree::
+   :maxdepth: 2
+
+
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
+

File docs/text.rst

+<?xml version="1.0" encoding="utf-8"?>
+<?xml-stylesheet href="webstring.css" type="text/css" media="screen" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>webstring: Introduction to TextTemplate</title>
+<link href="webstring.css" rel="stylesheet" type="text/css" media="screen" />
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+</head>
+<body>
+<div class="toc">
+<div class="entry"><a href="#classes">Class</a></div>
+<div class="entry"><a href="#initialization">Initialization</a></div>
+<div class="entry"><a href="#objects">Objects</a></div>
+<div class="entry"><a href="#dataaccess">Access</a></div>  <div class="entry"><a href="#sub">Substitution</a></div>
+<div class="entry"><a href="#batch">Batch Substitution</a></div>
+<div class="entry"><a href="#state">State</a></div>
+<div class="entry"><a href="#add">Concatenation </a></div>  <div class="entry"><a href="#mul">Repetition</a></div>
+<div class="entry"><a href="#iter">Iteration</a></div>
+<div class="entry"><a href="#out">Output</a></div>
+</div>
+<div class="header"><img class="headerimg" src="webstring.gif" width="400" height="201" alt="webstring" />
+  <div class="headertext">Introduction to TextTemplate</div></div>
+<div class="textheader"><a id="classes">CLASS</a></div>
+<div class="textblock">While* webstring's *other specialized classes  
+  only handle XML and HTML templating, TextTemplate can handle templating for 
+  any text format, including XML and HTML.<br />
+  <br />
+  TextTemplate can be used as a standalone import: </div>
+  <div class="codeblock"><pre>&gt;&gt;&gt; <span class="keyword">from</span> webstring <span class="keyword">import</span> TextTemplate</pre></div>  
+<div class="textblock">It can also be used through *webstring's *Template 
+  class,  a  general frontend to all of *webstring's* specialized 
+  classes.</div>
+<div class="textheader"><a id="initialization">INITIALIZATION</a></div>
+<div class="textblock">A TextTemplate object can be initialized empty:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; exampleA = TextTemplate()</pre></div>
+<div class="textblock">From a file with the *fromfile* method:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; exampleB.fromfile(<span class="string">'example.rss'</span>)</pre></div>
+<div class="textblock">By passing the path to the file as the first argument to the class constructor:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; exampleC = TextTemplate(<span class="string">'example.rss'</span>)</pre></div>
+<div class="textblock">From a string with the *fromstring* method:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; exampleD = TextTemplate.fromstring(<span class="string">&quot;&quot;&quot;&lt;rss version=&quot;2.0&quot;&gt;</span><br />...  <span class="string">&lt;channel&gt;</span><br />...   <span class="string">&lt;title&gt;Example&lt;/title&gt;</span><br />...   <span class="string">&lt;link&gt;http://www.example.org/&lt;/link&gt;</span><br />...   <span class="string">&lt;description&gt;RSS Example&lt;/description&gt;</span><br />...   <span class="string">&lt;language&gt;en-us&lt;/language&gt;</span><br />...   <span class="string">$$cpubdate&lt;pubDate&gt;$month$ $day$, $year$&lt;/pubDate&gt;$$</span><br />...   <span class="string">$$lastbuilddate&lt;lastBuildDate&gt;$month$ $day$, $year$&lt;/lastBuildDate&gt;$$</span>
+...   <span class="string">$$item&lt;item&gt;</span><br />...    <span class="string">&lt;title&gt;$title$&lt;/title&gt;</span><br />...    <span class="string">&lt;link&gt;$link$&lt;/link&gt;</span><br />...    <span class="string">&lt;guid isPermaLink=&quot;true&quot;&gt;$guid$&lt;/guid&gt;</span><br />...    <span class="string">&lt;description&gt;$description$&lt;/description&gt;</span><br />...    <span class="string">&lt;pubDate&gt;$ipubdate$&lt;/pubDate&gt;</span><br />...   <span class="string">&lt;/item&gt;</span><br />...  <span class="string">$$&lt;/channel&gt;</span><br />...  <span class="string">&lt;/rss&gt;&quot;&quot;&quot;</span>)</pre></div>
+<div class="textblock">By passing a string as  the first argument  to the class constructor:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example = TextTemplate(<span class="string">&quot;&quot;&quot;&lt;rss version=&quot;2.0&quot;&gt;</span><br />...  <span class="string">&lt;channel&gt;</span><br />...   <span class="string">&lt;title&gt;Example&lt;/title&gt;</span><br />...   <span class="string">&lt;link&gt;http://www.example.org/&lt;/link&gt;</span><br />...   <span class="string">&lt;description&gt;RSS Example&lt;/description&gt;</span><br />...   <span class="string">&lt;language&gt;en-us&lt;/language&gt;</span><br />...   <span class="string">$$cpubdate&lt;pubDate&gt;$month$ $day$, $year$&lt;/pubDate&gt;$$</span><br />...   <span class="string">$$lastbuilddate&lt;lastBuildDate&gt;$month$ $day$, $year$&lt;/lastBuildDate&gt;$$</span>
+...   <span class="string">$$item&lt;item&gt;</span><br />...    <span class="string">&lt;title&gt;$title$&lt;/title&gt;</span><br />...    <span class="string">&lt;link&gt;$link$&lt;/link&gt;</span><br />...    <span class="string">&lt;guid isPermaLink=&quot;true&quot;&gt;$guid$&lt;/guid&gt;</span><br />...    <span class="string">&lt;description&gt;$description$&lt;/description&gt;</span><br />...    <span class="string">&lt;pubDate&gt;$ipubdate$&lt;/pubDate&gt;</span><br />...   <span class="string">&lt;/item&gt;</span><br />...  <span class="string">$$&lt;/channel&gt;</span><br />...  <span class="string">&lt;/rss&gt;&quot;&quot;&quot;</span>)</pre></div>
+<div class="textblock">To use TextTemplate through  the  Template class, you 
+  pass the value *text * with the *format* keyword to the Template class's constructor:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example = Template(format="text")</pre></div>	    
+<div class="textheader"><a id="objects">OBJECTS</a></div>
+<div class="textblock">*webstring* automatically maps a template to a root 
+  object. Field placeholders within the template are an alphanumeric value that 
+  uniquely identifies the field placeholder within the template preceded and terminated 
+  by a placeholder marker (by default, <strong>$</strong>). Field placeholders 
+  are automatically mapped to field objects with the same name as the field placeholder 
+  and attached to the parent template's root object.</div>
+<div class="codeblock"><pre class="stdout">$$cpubdate&lt;pubDate&gt;<span class="highlight">$month$</span> $day$, $year$&lt;/pubDate&gt;$$</pre></div>
+<div class="textblock">Group placeholders within the template are blocks of text 
+  containing field placeholders preceded and terminated by a group placeholder 
+  marker (by default, <strong>$$</strong>). The alphanumeric value immediately 
+  following the opening group placeholder marker uniquely identifies the group 
+  within the template. *webstring* automatically maps the group placeholder 
+  to a group object with the same name as the group placeholder and attaches it 
+  to the parent template's root object. Field placeholders within group are mapped 
+  to field objects and attached to the group object.</div>
+<div class="codeblock"><pre class="stdout"><span class="highlight">$$cpubdate</span>&lt;pubDate&gt;$month$ $day$, $year$&lt;/pubDate&gt;<span class="highlight">$$</span></pre></div>
+<div class="textblock">Group objects cannot contain other group objects. At maximum, a root's object hierarchy will never be more than three levels deep.<br />
+  <br />Root level:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example<br /><span class="stdout">&lt;Template &quot;root&quot; at db7dd0&gt;</span></pre></div>
+<div class="textblock">Group level:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.item<br /><span class="stdout">&lt;Template &quot;item&quot; at f5d870&gt;</span></pre></div>
+<div class="textblock">Field level:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.item.guid<br /><span class="stdout">&lt;Template &quot;guid&quot; at f5da70&gt;</span></pre></div>
+<div class="textblock">At minimum, a root object's depth will only be two levels deep.<br /><br />Root level:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example<br /><span class="stdout">&lt;Template &quot;root&quot; at db7dd0&gt;</span></pre></div>
+<div class="textblock">Field level:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.cpubdate<br /><span class="stdout">&lt;Template &quot;cpubdate&quot; at e7a350&gt;</span></pre></div>
+<div class="textblock">By default, all field or group placeholders become part 
+  of a root's object hierarchy except for groups that have no field placeholders 
+  within them. However, existing fields or groups within an template can be excluded 
+  or included before or after a root object is initialized by using its *exclude* 
+  or *include* methods.<br />
+  <br />
+  Exclusion with the *exclude* method:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.exclude(<span class="string">'cpubdate'</span>) <br />&gt;&gt;&gt; <span class="keyword">print</span> example<br /><span class="stdout">&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  &lt;lastBuildDate&gt; , &lt;/lastBuildDate&gt;<br />  &lt;item&gt;<br />   &lt;title&gt;&lt;/title&gt;<br />   &lt;link&gt;&lt;/link&gt;<br />   &lt;guid isPermaLink=&quot;true&quot;&gt;&lt;/guid&gt;<br />   &lt;description&gt;&lt;/description&gt;<br />   &lt;pubDate&gt;&lt;/pubDate&gt;<br />  &lt;/item&gt;<br /> &lt;/channel&gt;<br /> &lt;/rss&gt;</span></pre></div>
+<div class="textblock">Inclusion with the *include* method:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.include(<span class="string">'cpubdate'</span>)<br />&gt;&gt;&gt; <span class="keyword">print</span> example<br /><span class="stdout">&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  </span><span class="highlight">&lt;pubDate&gt; , &lt;/pubDate&gt;</span><span class="stdout"><br />  &lt;lastBuildDate&gt; , &lt;/lastBuildDate&gt;
+  &lt;item&gt;<br />   &lt;title&gt;&lt;/title&gt;<br />   &lt;link&gt;&lt;/link&gt;<br />   &lt;guid isPermaLink=&quot;true&quot;&gt;&lt;/guid&gt;<br />   &lt;description&gt;&lt;/description&gt;<br />   &lt;pubDate&gt;&lt;/pubDate&gt;<br />  &lt;/item&gt;<br /> &lt;/channel&gt;<br /> &lt;/rss&gt;</span></pre></div>
+<div class="textblock">Fields and groups can  be removed by deleting
+  their object attribute:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; <span class="keyword">del</span> example.cpubdate<br />&gt;&gt;&gt; <span class="keyword">print</span> example<br /><span class="stdout">&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  &lt;lastBuildDate&gt; , &lt;/lastBuildDate&gt;<br />  &lt;item&gt;<br />   &lt;title&gt;&lt;/title&gt;<br />   &lt;link&gt;&lt;/link&gt;<br />   &lt;guid isPermaLink=&quot;true&quot;&gt;&lt;/guid&gt;<br />   &lt;description&gt;&lt;/description&gt;<br />   &lt;pubDate&gt;&lt;/pubDate&gt;<br />  &lt;/item&gt;<br /> &lt;/channel&gt;<br /> &lt;/rss&gt;</span></pre></div>
+<div class="textblock">A root, field, or group can be set back to its default state by calling
+  its *reset* method:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.reset()<br />&gt;&gt;&gt; <span class="keyword">print</span> example<br /><span class="stdout">&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  &lt;pubDate&gt; , &lt;/pubDate&gt;<br />  &lt;lastBuildDate&gt; , &lt;/lastBuildDate&gt;
+  &lt;item&gt;<br />   &lt;title&gt;&lt;/title&gt;<br />   &lt;link&gt;&lt;/link&gt;<br />   &lt;guid isPermaLink=&quot;true&quot;&gt;&lt;/guid&gt;<br />   &lt;description&gt;&lt;/description&gt;<br />   &lt;pubDate&gt;&lt;/pubDate&gt;<br />  &lt;/item&gt;<br /> &lt;/channel&gt;<br /> &lt;/rss&gt;</span></pre></div>
+<div class="textheader"><a id="dataaccess">ACCESS</a></div>
+<div class="textblock">Fields can be accessed by object attribute:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.cpubdate<br /><span class="stdout">&lt;Template &quot;cpubdate&quot; at e7a350&gt;</span></pre></div>
+<div class="textblock">By keyword:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example[<span class="string">'cpubdate'</span>]<br /><span class="stdout">&lt;Template &quot;cpubdate&quot; at e7a350&gt;</span></pre></div>
+<div class="textblock">By position:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example[<span class="int">0</span>]<br /><span class="stdout">&lt;Template &quot;cpubdate&quot; at e7a350&gt;</span></pre></div>
+<div class="textblock">Groups are accessed the same way:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.item <br /><span class="stdout">&lt;Template &quot;item&quot; at f5d870&gt;</span><br />&gt;&gt;&gt; example[<span class="string">'item'</span>]<br /><span class="stdout">&lt;Template &quot;item&quot; at f5d870&gt;</span><br />&gt;&gt;&gt; example[<span class="int">2</span>]<br /><span class="stdout">&lt;Template &quot;item&quot; at f5d870&gt;</span></pre></div>
+<div class="textblock">Fields within a group are accessed by combining its identifier and  its group identifier:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.item.title <br /><span class="stdout">&lt;Template &quot;title&quot; at f5d9b0&gt;</span><br />&gt;&gt;&gt; example[<span class="string">'item'</span>][<span class="string">'title'</span>]<br /><span class="stdout">&lt;Template &quot;title&quot; at f5d9b0&gt;</span><br />&gt;&gt;&gt; example[<span class="int">2</span>][<span class="int">0</span>]<br /><span class="stdout">&lt;Template &quot;title&quot; at f5d9b0&gt;</span></pre></div>
+<div class="textblock">By default, *webstring* automatically maps fields, 
+  groups, and attributes to object attributes with the same name as the field 
+  or group placeholder's identifier. This &quot;auto-magical&quot; behavior can 
+  be disabled by passing a boolean value of <span class="keyword">False</span> 
+  to the class constructor as the second argument when a TextTemplate object is 
+  initialized:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; exampleZ = TextTemplate(<span class="string">'example.rss', </span><span class="keyword">False</span>)</pre></div>
+<div class="textblock">Fields and groups can then be accessed by keyword or position 
+  but not by named object attribute.</div>
+<div class="textheader"><a id="sub">SUBSTITUTION</a></div>
+<div class="textblock">Text can be substituted into a field by assigning a string to a field's text property:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.item.description.text = <span class="string">'Assigning text to a field.'</span>
+&gt;&gt;&gt; <span class="keyword">print</span> example<br /><span class="stdout">&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  &lt;pubDate&gt; , &lt;/pubDate&gt;<br />  &lt;lastBuildDate&gt; , &lt;/lastBuildDate&gt;
+  &lt;item&gt;<br />   &lt;title&gt;&lt;/title&gt;<br />   &lt;link&gt;&lt;/link&gt;<br />   &lt;guid isPermaLink=&quot;true&quot;&gt;&lt;/guid&gt;<br />   &lt;description&gt;</span><span class="highlight">Assigning text to a field.</span><span class="stdout">&lt;/description&gt;<br />   &lt;pubDate&gt;&lt;/pubDate&gt;<br />  &lt;/item&gt;<br />  &lt;/channel&gt;<br /> &lt;/rss&gt;</span></pre></div>
+<div class="textblock">Alternatively, text can be substituted into a field using 
+  the modulo assignment operator (<strong>%=</strong>). Using the modulo operator without the assignment operator 
+    (<strong>%</strong>) creates a new object. Using the modulo operator with 
+    the assignment operator (<strong>%=</strong>) modifies the left-hand object.</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.item.description %= <span class="string">'Example of assigning text to a field.'</span>
+&gt;&gt;&gt; <span class="keyword">print</span> example<br /><span class="stdout">&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  &lt;pubDate&gt; , &lt;/pubDate&gt;<br />  &lt;lastBuildDate&gt; , &lt;/lastBuildDate&gt;
+  &lt;item&gt;<br />   &lt;title&gt;&lt;/title&gt;<br />   &lt;link&gt;&lt;/link&gt;<br />   &lt;guid isPermaLink=&quot;true&quot;&gt;&lt;/guid&gt;<br />   &lt;description&gt;</span><span class="highlight">Example of assigning text to a field.</span><span class="stdout">&lt;/description&gt;<br />   &lt;pubDate&gt;&lt;/pubDate&gt;<br />  &lt;/item&gt;<br />  &lt;/channel&gt;<br /> &lt;/rss&gt;</span></pre></div>
+<div class="textblock">The <strong>%= </strong>operator can also be used to substitute 
+  text into a group using a dictionary containing key/value pairs where the key is the name of the field 
+  inside the group and the value is the text that will be assigned to the field:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.cpubdate %= {<span class="string">'month'</span>:<span class="string">'June'</span>, <span class="string">'day'</span>:<span class="string">'06'</span>, <span class="string">'year'</span>:<span class="string">'2006'</span>}
+&gt;&gt;&gt; example.lastbuilddate %= {<span class="string">'month'</span>:<span class="string">'June'</span>, <span class="string">'day'</span>:<span class="string">'06'</span>, <span class="string">'year'</span>:<span class="string">'2006'</span>}<br />&gt;&gt;&gt; <span class="keyword">print</span> example<br /><span class="stdout">&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  &lt;pubDate&gt;</span><span class="highlight">June 06, 2006</span><span class="stdout">&lt;/pubDate&gt;<br />  &lt;lastBuildDate&gt;</span><span class="highlight">June 06, 2006</span><span class="stdout">&lt;/lastBuildDate&gt;
+  &lt;item&gt;<br />   &lt;title&gt;&lt;/title&gt;<br />   &lt;link&gt;&lt;/link&gt;<br />   &lt;guid isPermaLink=&quot;true&quot;&gt;&lt;/guid&gt;<br />   &lt;description&gt;Example of assigning text to a field.&lt;/description&gt;<br />   &lt;pubDate&gt;&lt;/pubDate&gt;</span><span class="stdout"><br />  &lt;/item&gt;<br /> &lt;/channel&gt;<br /> &lt;/rss&gt;</span></pre></div>
+<div class="textheader"><a id="batch">BATCH SUBSTITUTION</a></div>
+<div class="textblock">The modulo operator can also be used to substitute text into a template in 
+    one batch substitution. 
+    Text values for fields and groups within a template are passed in a dictionary 
+    containing key/value pairs where the key is the field or group identifier 
+    and the value is the text to be substituted. Fields within a group are passed 
+    in a dictionary that is stored under the keyword identifying the group:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example %= {<br />... <span class="string">'cpubdate'</span>:{<span class="string">'month'</span>:<span class="string">'June'</span>, <span class="string">'day'</span>:<span class="string">'06'</span>, <span class="string">'year'</span>:<span class="string">'2006'</span>}, <br />... <span class="string">'lastbuilddate'</span>:{<span class="string">'month'</span>:<span class="string">'June'</span>, <span class="string">'day'</span>:<span class="string">'06'</span>, <span class="string">'year'</span>:<span class="string">'2006'</span>},<br />... <span class="string">'item'</span>:{<span class="string">'title'</span>:<span class="string">Example Title: First Example'</span>,<br />... 	<span class="string">'link'</span>:'<span class="string">http://www.example.org/rss/5423093'</span>,<br />... 	<span class="string">'guid'</span>:'<span class="string">http://www.example.org/rss/5423093'</span>,<br />... 	<span class="string">'description'</span>:<span class="string">'Example of assigning text to a field.'</span>,<br />... 	<span class="string">'ipubdate'</span>:<span class="string">'June </span><span class="string">6, </span><span class="string">2006'</span>}}<br />&gt;&gt;&gt; <span class="keyword">print</span> example<br /><span class="stdout">&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  &lt;pubDate&gt;</span><span class="highlight">June 06, 2006</span><span class="stdout">&lt;/pubDate&gt;<br />  &lt;lastBuildDate&gt;</span><span class="highlight">June 06, 2006</span><span class="stdout">&lt;/lastBuildDate&gt;<br />  &lt;item&gt;<br />   &lt;title&gt;</span><span class="highlight">Example Title: First Example</span><span class="stdout">&lt;/title&gt;<br />   &lt;link&gt;</span><span class="highlight">http://www.example.org/rss/5423093</span><span class="stdout">&lt;/link&gt;<br />   &lt;guid </span><span class="stdout">isPermaLink=&quot;true&quot;&gt;</span><span class="highlight">http://www.example.org/rss/5423093</span><span class="stdout">&lt;/guid&gt;<br />   &lt;description&gt;</span><span class="highlight">Example of assigning text to a field.</span><span class="stdout">&lt;/description&gt;<br />   &lt;pubDate&gt;</span><span class="highlight">June 06, 2006</span><span class="stdout">&lt;/pubDate&gt;<br />  &lt;/item&gt;<br /> &lt;/channel&gt;<br /> &lt;/rss&gt;</span></pre></div>
+<div class="textheader"><a id="state">STATE</a></div>
+<div class="textblock">Each root, field, or group has a *current* and a *default* property. The *current* property returns the object's current state:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.current<br /><span class="stdout">&lt;Template &quot;root&quot; at dcd290&gt;</span><br />&gt;&gt;&gt; <span class="keyword">print</span> example.current<br /><span class="stdout">&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  &lt;pubDate&gt;June 06, 2006&lt;/pubDate&gt;<br />  &lt;lastBuildDate&gt;June 06, 2006&lt;/lastBuildDate&gt;<br />  &lt;item&gt;<br />   &lt;title&gt;Example Title: First Example&lt;/title&gt;<br />   &lt;link&gt;http://www.example.org/rss/5423093&lt;/link&gt;<br />   &lt;guid isPermaLink=&quot;true&quot;&gt;http://www.example.org/rss/5423093&lt;/guid&gt;<br />   &lt;description&gt;Example of assigning text to a field.&lt;/description&gt;<br />   &lt;pubDate&gt;June 06, 2006&lt;/pubDate&gt;<br />  &lt;/item&gt;<br /> &lt;/channel&gt;<br /> &lt;/rss&gt;</span></pre></div>
+<div class="textblock">The *default* property returns the object's
+  default state:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.default<br /><span class="stdout">&lt;Template &quot;root&quot; at f62d10&gt;</span><br />&gt;&gt;&gt; <span class="keyword">print</span> example.default<br /><span class="stdout">&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  &lt;pubDate&gt; , &lt;/pubDate&gt;<br />  &lt;lastBuildDate&gt; , &lt;/lastBuildDate&gt;
+  &lt;item&gt;<br />   &lt;title&gt;&lt;/title&gt;<br />   &lt;link&gt;&lt;/link&gt;<br />   &lt;guid isPermaLink=&quot;true&quot;&gt;&lt;/guid&gt;<br />   &lt;description&gt;&lt;/description&gt;<br />   &lt;pubDate&gt;&lt;/pubDate&gt;<br />  &lt;/item&gt;<br /> &lt;/channel&gt;<br /> &lt;/rss&gt;</span></pre></div>
+<div class="textheader"><a id="add">CONCATENATION</a></div>
+<div class="textblock">Roots, fields, and groups can be concatenated together using the addition operator.<br /><br />Roots:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.reset()<br />&gt;&gt;&gt; <span class="keyword">print</span> example + example<br /><span class="stdout">&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  &lt;pubDate&gt; , &lt;/pubDate&gt;<br />  &lt;lastBuildDate&gt; , &lt;/lastBuildDate&gt;
+  &lt;item&gt;<br />   &lt;title&gt;&lt;/title&gt;<br />   &lt;link&gt;&lt;/link&gt;<br />   &lt;guid isPermaLink=&quot;true&quot;&gt;&lt;/guid&gt;<br />   &lt;description&gt;&lt;/description&gt;<br />   &lt;pubDate&gt;&lt;/pubDate&gt;<br />  &lt;/item&gt;<br /> &lt;/channel&gt;<br /> &lt;/rss&gt;</span><span class="highlight">&lt;rss version=&quot;2.0&quot;&gt;
+ &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br /></span>  <span class="highlight">&lt;pubDate&gt; , &lt;/pubDate&gt;<br />  &lt;lastBuildDate&gt; , &lt;/lastBuildDate&gt;
+  &lt;item&gt;<br />   &lt;title&gt;&lt;/title&gt;<br />   &lt;link&gt;&lt;/link&gt;<br />   &lt;guid isPermaLink=&quot;true&quot;&gt;&lt;/guid&gt;<br />   &lt;description&gt;&lt;/description&gt;<br />   &lt;pubDate&gt;&lt;/pubDate&gt;<br />  &lt;/item&gt;<br /> &lt;/channel&gt;
+ &lt;/rss&gt;</span></pre></div>
+<div class="textblock">Groups:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; <span class="keyword">print</span> example.item + example.item<br /><span class="stdout">&lt;item&gt;<br />   &lt;title&gt;&lt;/title&gt;<br />   &lt;link&gt;&lt;/link&gt;<br />   &lt;guid isPermaLink=&quot;true&quot;&gt;&lt;/guid&gt;<br />   &lt;description&gt;&lt;/description&gt;<br />   &lt;pubDate&gt;&lt;/pubDate&gt;<br />  &lt;/item&gt;<br /> </span><span class="highlight">&lt;item&gt;<br />   &lt;title&gt;&lt;/title&gt;<br />   &lt;link&gt;&lt;/link&gt;<br />   &lt;guid isPermaLink=&quot;true&quot;&gt;&lt;/guid&gt;<br />   &lt;description&gt;&lt;/description&gt;<br />   &lt;pubDate&gt;&lt;/pubDate&gt;<br />  &lt;/item&gt;</span></pre></div>
+<div class="textblock">Concatenating empty fields produces no output:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; <span class="keyword">print</span> example.item.title + example.item.title<br /></pre>
+</div>
+<div class="textblock">Using the addition operator (<strong>+</strong>) without the assignment operator (<strong>=</strong>) results in a new object. Using
+  the addition and assignment operators together (<strong>+=</strong>) modifies the left-hand object:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.item += example.item<br />&gt;&gt;&gt; <span class="keyword">print</span> example<br /><span class="stdout">&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  &lt;pubDate&gt; , &lt;/pubDate&gt;<br />  &lt;lastBuildDate&gt; , &lt;/lastBuildDate&gt;
+  &lt;item&gt;<br />   &lt;title&gt;&lt;/title&gt;<br />   &lt;link&gt;&lt;/link&gt;<br />   &lt;guid isPermaLink=&quot;true&quot;&gt;&lt;/guid&gt;<br />   &lt;description&gt;&lt;/description&gt;<br />   &lt;pubDate&gt;&lt;/pubDate&gt;<br />  &lt;/item&gt;<br /></span><span class="highlight">  &lt;item&gt;<br />   &lt;title&gt;&lt;/title&gt;<br />   &lt;link&gt;&lt;/link&gt;<br />   &lt;guid isPermaLink=&quot;true&quot;&gt;&lt;/guid&gt;<br />   &lt;description&gt;&lt;/description&gt;<br />   &lt;pubDate&gt;&lt;/pubDate&gt;<br />  &lt;/item&gt;</span><span class="stdout"><br /> &lt;/channel&gt;<br /> &lt;/rss&gt;</span></pre></div>
+<div class="textblock">Other Template objects or strings can be appended  to a root, field, or group using their* append* method.</div>
+<div class="textheader"><a id="mul">REPETITION</a></div>
+<div class="textblock">A root, group, or field can be repeated once by calling its *repeat* method:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.reset()<br />&gt;&gt;&gt; example.item.repeat()<br />&gt;&gt;&gt; <span class="keyword">print</span> example<br /><span class="stdout">&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  &lt;pubDate&gt; , &lt;/pubDate&gt;<br />  &lt;lastBuildDate&gt; , &lt;/lastBuildDate&gt;
+  &lt;item&gt;<br />   &lt;title&gt;&lt;/title&gt;<br />   &lt;link&gt;&lt;/link&gt;<br />   &lt;guid isPermaLink=&quot;true&quot;&gt;&lt;/guid&gt;<br />   &lt;description&gt;&lt;/description&gt;<br />   &lt;pubDate&gt;&lt;/pubDate&gt;<br />  &lt;/item&gt;<br /></span><span class="highlight">  &lt;item&gt;<br />   &lt;title&gt;&lt;/title&gt;<br />   &lt;link&gt;&lt;/link&gt;<br />   &lt;guid isPermaLink=&quot;true&quot;&gt;&lt;/guid&gt;<br />   &lt;description&gt;&lt;/description&gt;<br />   &lt;pubDate&gt;&lt;/pubDate&gt;<br />  &lt;/item&gt;</span><span class="stdout"><br /> &lt;/channel&gt;<br /> &lt;/rss&gt;</span></pre></div>
+<div class="textblock">A root, group, or field can be repeated more than once by using the multiplication operator, either by itself (<strong>*</strong>),
+  which returns a new object, or along with the assignment operator (<strong>*=</strong>), which modifies the left-hand object:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.reset()<br />&gt;&gt;&gt; example.item *= <span class="int">2</span><br />&gt;&gt;&gt; <span class="keyword">print</span> example<br /><span class="stdout">&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  &lt;pubDate&gt; , &lt;/pubDate&gt;<br />  &lt;lastBuildDate&gt; , &lt;/lastBuildDate&gt;
+  &lt;item&gt;<br />   &lt;title&gt;&lt;/title&gt;<br />   &lt;link&gt;&lt;/link&gt;<br />   &lt;guid isPermaLink=&quot;true&quot;&gt;&lt;/guid&gt;<br />   &lt;description&gt;&lt;/description&gt;<br />   &lt;pubDate&gt;&lt;/pubDate&gt;<br />  &lt;/item&gt;<br /></span><span class="highlight">  &lt;item&gt;<br />   &lt;title&gt;&lt;/title&gt;<br />   &lt;link&gt;&lt;/link&gt;<br />   &lt;guid isPermaLink=&quot;true&quot;&gt;&lt;/guid&gt;<br />   &lt;description&gt;&lt;/description&gt;<br />   &lt;pubDate&gt;&lt;/pubDate&gt;<br />  &lt;/item&gt;</span><span class="stdout"><br /> &lt;/channel&gt;<br /> &lt;/rss&gt;</span></pre></div>
+<div class="textblock">A root, field, or group can be repeated and have text substituted into it by passing a string, tuple, or dictionary to its *repeat*
+  method:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.reset()<br />&gt;&gt;&gt; example.item %= (
+... <span class="string">'Example Title: First Example'</span>,
+... <span class="string">'http://www.example.org/rss/5423092'</span>,
+... <span class="string">'http://www.example.org/rss/5423092'</span>,
+... <span class="string">'Example of assigning text to a field.'</span>,
+... <span class="string">'June 06, 2006'</span>)<br />&gt;&gt;&gt; example.item.repeat((
+... <span class="string">'Example Title: Second Example'</span>,
+... <span class="string">'http://www.example.org/rss/5423093'</span>,
+... <span class="string">'http://www.example.org/rss/5423093'</span>,
+... <span class="string">'Example of group repetition.'</span>,
+... <span class="string">'June 06, 2006'</span>))<br />&gt;&gt;&gt; <span class="keyword">print</span> example<br /><span class="stdout">&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  &lt;pubDate&gt; , &lt;/pubDate&gt;<br />  &lt;lastBuildDate&gt; , &lt;/lastBuildDate&gt;<br />  &lt;item&gt;<br />   &lt;title&gt;</span><span class="highlight">Example Title: First Example</span><span class="stdout">&lt;/title&gt;<br />   &lt;link&gt;</span><span class="highlight">http://www.example.org/rss/5423092</span><span class="stdout">&lt;/link&gt;<br />   &lt;guid isPermaLink=&quot;true&quot;&gt;</span><span class="highlight">http://www.example.org/rss/5423092</span><span class="stdout">&lt;/guid&gt;<br />   &lt;description&gt;</span><span class="highlight">Example of assigning text to a field.</span><span class="stdout">&lt;/description&gt;<br />   &lt;pubDate&gt;</span><span class="highlight">June 06, 2006</span><span class="stdout">&lt;/pubDate&gt;<br />  &lt;/item&gt;<br /> </span><span class="highlight">&lt;item&gt;<br />   &lt;title&gt;Example Title: Second Example&lt;/title&gt;<br />   &lt;link&gt;http://www.example.org/rss/5423093&lt;/link&gt;<br />   &lt;guid isPermaLink=&quot;true&quot;&gt;http://www.example.org/rss/5423093&lt;/guid&gt;<br />   &lt;description&gt;Example of group repetition.&lt;/description&gt;<br />   &lt;pubDate&gt;June 06, 2006&lt;/pubDate&gt;<br />  &lt;/item&gt;</span><span class="stdout"><br /> &lt;/channel&gt;<br /> &lt;/rss&gt;</span></pre></div>
+<div class="textblock">A root, field, or group can be expanded to fit a sequence of substitutions by using the power operator (<strong>**</strong>) either alone,
+  which returns a new object, or joined with the assignment operator (<strong>**=</strong>), which modifies the left-hand object:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.reset()<br />&gt;&gt;&gt; example.item **= ((
+... <span class="string">'Example Title: First Example'</span>,
+... <span class="string">'http://www.example.org/rss/5423092'</span>,
+... <span class="string">'http://www.example.org/rss/5423092'</span>,
+... <span class="string">'Example of assigning text to a field.'</span>,
+... <span class="string">'June 06, 2006'</span>), (
+... <span class="string">'Example Title: Second Example'</span>,
+... <span class="string">'http://www.example.org/rss/5423093'</span>,
+... <span class="string">'http://www.example.org/rss/5423093'</span>,
+... <span class="string">'Example of group repetition.'</span>,
+... <span class="string">'June 06, 2006'</span>))<br />&gt;&gt;&gt; <span class="keyword">print</span> example<br /><span class="stdout">&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  &lt;pubDate&gt; , &lt;/pubDate&gt;<br />  &lt;lastBuildDate&gt; , &lt;/lastBuildDate&gt;<br />  &lt;item&gt;<br />   &lt;title&gt;</span><span class="highlight">Example Title: First Example</span><span class="stdout">&lt;/title&gt;<br />   &lt;link&gt;</span><span class="highlight">http://www.example.org/rss/5423092</span><span class="stdout">&lt;/link&gt;<br />   &lt;guid isPermaLink=&quot;true&quot;&gt;</span><span class="highlight">http://www.example.org/rss/5423092</span><span class="stdout">&lt;/guid&gt;<br />   &lt;description&gt;</span><span class="highlight">Example of assigning text to a field.</span><span class="stdout">&lt;/description&gt;<br />   &lt;pubDate&gt;</span><span class="highlight">June 06, 2006</span><span class="stdout">&lt;/pubDate&gt;<br />  &lt;/item&gt;<br /> </span><span class="highlight">&lt;item&gt;<br />   &lt;title&gt;Example Title: Second Example&lt;/title&gt;<br />   &lt;link&gt;http://www.example.org/rss/5423093&lt;/link&gt;<br />   &lt;guid isPermaLink=&quot;true&quot;&gt;http://www.example.org/rss/5423093&lt;/guid&gt;<br />   &lt;description&gt;Example of group repetition.&lt;/description&gt;<br />   &lt;pubDate&gt;June 06, 2006&lt;/pubDate&gt;<br />  &lt;/item&gt;</span><span class="stdout"><br /> &lt;/channel&gt;<br /> &lt;/rss&gt;</span></pre></div>
+<div class="textblock">The number of items in each tuple of substitutions must be equal to the number of fields in the root or group to which it is passed.<br />
+  <br />
+  The maximum number of repetitions  that can be performed on a root, field, or group is controlled by the *max* property. Assigning a new
+  maximum number of repetitions to the *max* property assigns the same number to a root or group's child fields or groups. The default value of the *max*
+  property is 25. Exceeding the maximum repetition value assigned to the *max* property triggers an exception:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.reset()<br />&gt;&gt;&gt; example.max = <span class="int">1</span><br />&gt;&gt;&gt; example.item **= ((
+... <span class="string">'Example Title: First Example'</span>,
+... <span class="string">'http://www.example.org/rss/5423092'</span>,
+... <span class="string">'http://www.example.org/rss/5423092'</span>,
+... <span class="string">'Example of assigning text to a field.'</span>,
+... <span class="string">'June 06, 2006'</span>), (
+... <span class="string">'Example Title: Second Example'</span>,
+... <span class="string">'http://www.example.org/rss/5423093'</span>,
+... <span class="string">'http://www.example.org/rss/5423093'</span>,
+... <span class="string">'Example of group repetition.'</span>,
+... <span class="string">'June 06, 2006'</span>))<br /><span class="highlight">Traceback (most recent call last):<br />  File &quot;&lt;interactive input&gt;&quot;, line 1, in ?<br />  File &quot;base.py&quot;, line 158, in __ipow__<br />    raise TypeError(_exceptions[0])<br />TypeError: maximum allowed repetitions exceeded</span></pre></div>
+<div class="textblock">Setting the *max* property to a number greater than 1 allows the operation to be completed successfully.</div>
+<div class="textheader"><a id="iter">ITERATION</a></div>
+<div class="textblock">Performing a loop operation on a root or group iterates over  its    fields or groups in sequence:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; <span class="keyword">for</span> field <span class="keyword">in</span> example: field.__repr__()<br />... <br /><span class="stdout">'&lt;Template &quot;cpubdate&quot; at f62f50&gt;'<br />'&lt;Template &quot;lastbuilddate&quot; at e7a350&gt;'<br />'&lt;Template &quot;item&quot; at f627f0&gt;'</span></pre></div>
+<div class="textheader"><a id="out">OUTPUT</a></div>
+<div class="textblock">The *render* method is called to output an template as  a string:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; <span class="keyword">print</span> example.render()<br /><span class="stdout">&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  &lt;pubDate&gt; , &lt;/pubDate&gt;<br />  &lt;lastBuildDate&gt; , &lt;/lastBuildDate&gt;<br />  &lt;item&gt;<br />   &lt;title&gt;Example Title: First Example&lt;/title&gt;<br />   &lt;link&gt;http://www.example.org/rss/5423092&lt;/link&gt;<br />   &lt;guid isPermaLink=&quot;true&quot;&gt;http://www.example.org/rss/5423092&lt;/guid&gt;<br />   &lt;description&gt;Example of assigning text to a field.&lt;/description&gt;<br />   &lt;pubDate&gt;June 06, 2006&lt;/pubDate&gt;<br />  &lt;/item&gt;<br /> &lt;item&gt;<br />   &lt;title&gt;Example Title: Second Example&lt;/title&gt;<br />   &lt;link&gt;http://www.example.org/rss/5423093&lt;/link&gt;<br />   &lt;guid isPermaLink=&quot;true&quot;&gt;http://www.example.org/rss/5423093&lt;/guid&gt;<br />   &lt;description&gt;Example of group repetition.&lt;/description&gt;<br />   &lt;pubDate&gt;June 06, 2006&lt;/pubDate&gt;<br />  &lt;/item&gt;<br /> &lt;/channel&gt;<br /> &lt;/rss&gt;</span></pre></div>
+<div class="textblock">The *write* method is called to write a template's string output to a file:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.write(<span class="string">'finalexample.rss'</span>)</pre></div>
+<div class="textblock">The *pipe* method  outputs  a string  and resets the template  back to its default state:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; <span class="keyword">print</span> example.pipe()<br /><span class="stdout">&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  &lt;pubDate&gt; , &lt;/pubDate&gt;<br />  &lt;lastBuildDate&gt; , &lt;/lastBuildDate&gt;<br />  &lt;item&gt;<br />   &lt;title&gt;Example Title: First Example&lt;/title&gt;<br />   &lt;link&gt;http://www.example.org/rss/5423092&lt;/link&gt;<br />   &lt;guid isPermaLink=&quot;true&quot;&gt;http://www.example.org/rss/5423092&lt;/guid&gt;<br />   &lt;description&gt;Example of assigning text to a field.&lt;/description&gt;<br />   &lt;pubDate&gt;June 06, 2006&lt;/pubDate&gt;<br />  &lt;/item&gt;<br /> &lt;item&gt;<br />   &lt;title&gt;Example Title: Second Example&lt;/title&gt;<br />   &lt;link&gt;http://www.example.org/rss/5423093&lt;/link&gt;<br />   &lt;guid isPermaLink=&quot;true&quot;&gt;http://www.example.org/rss/5423093&lt;/guid&gt;<br />   &lt;description&gt;Example of group repetition.&lt;/description&gt;<br />   &lt;pubDate&gt;June 06, 2006&lt;/pubDate&gt;<br />  &lt;/item&gt;<br /> &lt;/channel&gt;<br /> &lt;/rss&gt;</span><br />&gt;&gt;&gt; <span class="keyword">print</span> example<span class="stdout"><br />&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  &lt;pubDate&gt; , &lt;/pubDate&gt;<br />  &lt;lastBuildDate&gt; , &lt;/lastBuildDate&gt;
+  &lt;item&gt;<br />   &lt;title&gt;&lt;/title&gt;<br />   &lt;link&gt;&lt;/link&gt;<br />   &lt;guid isPermaLink=&quot;true&quot;&gt;&lt;/guid&gt;<br />   &lt;description&gt;&lt;/description&gt;<br />   &lt;pubDate&gt;&lt;/pubDate&gt;<br />  &lt;/item&gt;<br /> &lt;/channel&gt;<br /> &lt;/rss&gt;</span></pre></div>
+<p>
+<a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-xhtml11" alt="Valid XHTML 1.1" height="31" width="88" /></a>
+</p>
+<div class="footer">Copyright 2007 L. C. Rees. All rights reserved.</div>
+</body>
+</html>

File docs/webstring.css

+.headertext {
+	font-family: Georgia, "Times New Roman", Times, serif;
+	font-size: 24px;
+	vertical-align: middle;
+	text-align: right;
+	display: block;
+}
+.header {
+	border: medium solid #000000;
+	height: 230px;
+	width: 700px;
+	left: 5px;
+	top: 5px;
+	margin: 5px;
+	padding: 5px;
+}
+.headerimg {
+	text-align: left;
+	display: block;
+}
+.textheader {
+	border-top-width: thin;
+	border-right-width: thin;
+	border-bottom-width: thin;
+	border-left-width: thin;
+	border-top-style: none;
+	border-right-style: none;
+	border-bottom-style: dashed;
+	border-left-style: none;
+	border-top-color: #000000;
+	border-right-color: #000000;
+	border-bottom-color: #000000;
+	border-left-color: #000000;
+	font-family: Verdana, Arial, Helvetica, sans-serif;
+	font-size: 16px;
+	font-weight: bold;
+	color: #000000;
+	padding: 15px 5px 5px;
+	height: 10px;
+	width: 700px;
+	text-align: left;
+	margin: 10px;
+}
+.textblock {
+	font-family: Verdana, Arial, Helvetica, sans-serif;
+	font-size: 14px;
+	font-style: normal;
+	font-weight: normal;
+	color: #000000;
+	text-decoration: none;
+	margin: 5px;
+	padding: 5px;
+	width: 700px;
+}
+em {
+	font-family: Verdana, Arial, Helvetica, sans-serif;
+	font-style: italic;
+
+}
+
+a {
+	text-decoration: none;
+}
+a:hover {
+	text-decoration: underline;
+}
+strong {
+	font-weight: bold;
+}
+.codeblock {
+	background-color: #FBFAE3;
+	white-space: pre;
+	font-family: "Courier New", Courier, mono;
+	margin: 5px;
+	padding: 5px 10px 5px 5px;
+	width: 690px;
+	overflow: auto;
+	border-right: thin;
+	border-bottom: thin;
+	border-left: thin;
+	font-weight: normal;
+}
+
+pre {
+	font-family: "Courier New", Courier, mono;
+	font-size: 14px;
+	margin: 0px;
+	padding: 0px;
+}
+
+.toc {
+	font-family: Verdana, Arial, Helvetica, sans-serif;
+	font-size: 16px;
+	width: 200px;
+	left: 730px;
+	top: 5px;
+	margin: 5px;
+	padding: 5px;
+	color: #000000;
+	border: thin solid #000000;
+	position: absolute;
+}
+
+.entry {
+	margin: 3px;
+	padding: 3px;
+}
+
+.footer {
+	font-family: Arial, Helvetica, sans-serif;
+	font-size: 9px;
+	color: #999999;
+}
+
+img {
+	border: 0px;
+}
+.string {
+	color: #999900;
+	font-weight: bold;
+
+
+}
+.stdout {
+	color: #408080;
+
+}
+.highlight {
+	color: #FF0000;
+	font-weight: bold;
+
+}
+.keyword {
+	font-weight: bold;
+	color: #000099;
+}
+.int {
+	color: cyan;
+	font-weight: bold;
+
+}

File docs/webstring.gif

Added
New image

File docs/webstring.rst

+<?xml version="1.0" encoding="utf-8"?>
+<?xml-stylesheet href="webstring.css" type="text/css" media="screen" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>webstring: A Python Template Engine</title>
+<link href="webstring.css" rel="stylesheet" type="text/css" media="screen" />
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+</head>
+<body>
+<div class="toc">
+<div class="entry"><a href="#whatisit">What is it?</a></div>
+<div class="entry"><a href="#license">License</a></div>
+<div class="entry"><a href="#download">Download</a></div>
+<div class="entry"><a href="#installation">Installation</a></div>
+<div class="entry"><a href="#requirements">Requirements</a></div>
+<div class="entry"><a href="#classes">Classes</a></div>
+<div class="entry"><a href="#initialization">Initialization</a></div>
+<div class="entry"><a href="#objects">Objects</a></div>
+<div class="entry"><a href="#dataaccess">Access</a></div>
+<div class="entry"><a href="#sub">Substitution</a></div>
+<div class="entry"><a href="#attr">Attributes</a></div>
+<div class="entry"><a href="#batch">Batch Substitution</a></div>
+<div class="entry"><a href="#state">State</a></div>
+<div class="entry"><a href="#add">Concatenation </a></div>
+<div class="entry"><a href="#mul">Repetition</a></div>
+<div class="entry"><a href="#append">Appending</a></div>
+<div class="entry"><a href="#iter">Iteration</a></div>
+<div class="entry"><a href="#out">Output</a></div>
+<div class="entry"><a href="#dev">Development</a></div>
+</div>
+<div class="header"><img class="headerimg" src="webstring.gif" width="400" height="201" alt="webstring" />
+  <div class="headertext">A Python Template Engine</div>
+</div>
+<div class="textheader"><a id="whatisit">WHAT IS IT?</a></div>
+<div class="textblock">
+<em>webstring</em> is a template engine for programmers 
+  whose favorite template language is <a href="http://www.python.org/">Python</a>. <em>webstring </em>can be used to generate any text output from a template with the additional advantages of advanced XML and HTML templating using the lxml and cElementTree libraries.
+  <em><br />
+  <br />
+    webstring </em>was designed to meet the following general goals:  
+  <ol>
+    <li><strong>To separate model and view logic from controller logic.</strong> 
+The advantages of using an MVC architecture are:<br />
+      <ul>
+        <li><strong>Clarity:</strong> it is easy to tell which parts of an application do what. Code is  clearer, more compact, and readable, 
+    which can make errors easier to spot, a  particularly important feature when 
+    more than one developer maintains the code.</li>
+        <li><strong>Modularity:</strong> model, view, or controller logic can be upgraded, reused, or replaced 
+    with little or no disruption to other parts of an application if they are 
+    not mixed together.</li>
+        <li>
+    <strong>Division of Labor:</strong> designers should design the view, programmers should 
+    program the controller, and data architects should design the model.</li>
+      </ul>
+      <br />
+	  <em>webstring </em>enforces MVC 
+    by following a pipeline or push template style: Python controller code has to explicitly 
+    push data into the template because a <em>webstring</em> template contains no callback 
+    logic and therefore cannot  itself request data from the controller.<br />
+          </li>
+    <li>
+<strong>To separate template logic from template data.</strong> Template data is text in the 
+    template that does not originate from an external source. Template logic controls 
+    a template's output when when template data and external data are mixed. Template 
+    data tells what a template is and template logic tells how it works. 
+            The advantages 
+    of keeping template data distinct from template logic are similar to the advantages 
+    of using an MVC architecture:<br />
+      <ul>
+        <li><strong>Clarity:</strong>  mental clarity is 
+    easily achieved when template data and template logic are encapsulated in 
+    separate, clearly distinct packages. webstring allows    template 
+    data to be kept in one file and  Python code, its  template logic, in another. 
+    Text data and logic are fundamentally different beasts: Text data is generally  a declarative data 
+    format that defines what  should be computed. Python is an imperative format that defines how computation 
+    should be performed. Separating them is the road to easier maintenance.</li>
+        <li><strong>Modularity:</strong> modular template data and template logic can be upgraded, reused, 
+    or replaced with little or no disruption to each other. <em>webstring</em>'s  placeholders are non-invasive markers. Many template engines use some kind 
+    of explicit or implicit logic for placeholders. This is not a modular approach: 
+    it sharply intertwines not only template logic and data but model, view, and 
+    controller logic. <em>webstring</em> keeps template data and template logic separate. Template logic does not have to know anything about 
+    the text half of a <em>webstring</em> template except for the name of its placeholders. 
+    Template data can be written without any structural awareness that it will 
+    ever be template data, let alone by controlled by external template logic 
+    written in Python. All it needs are placeholders that identify where external data can be inserted.</li>
+        <li><strong>Division of labor:</strong> separating template data from template logic allows for 
+    a clean separation of roles: Data architects can design text formats, designers 
+    can work on making text look good, and Python programmers can write 
+    controller code.<br />
+        </li>
+      </ul>
+    </li>
+    <li>
+<strong>To require only Python for templating.</strong> When templating   with Python, the minimum requirement is, of course, 
+    Python. <em>webstring</em> goes further: its design is based on the proposition 
+    that the <em>only</em> tool you need to template text with  Python is  Python.<br />
+      <br />
+             
+    Many template engines use a custom template language, usually with just enough 
+    logic to handle variable substitution, condition statements, and loops. Compared with the effort of templating  with C or Java, using a 
+    custom template language can be a giant step forward in programmer productivity. 
+    Using a custom template language with Python, however, is a giant step backwards.<br />
+      <br />
+    By design, Python places programmer productivity ahead of computer productivity, 
+    an approach that Bruce Eckel nicely summarized as  “Python fits your brain”. 
+    The average Python programmer can keep the core Python language in their head 
+    without constantly checking Python's documentation for information on basic 
+    language features. Layering another language on top of Python increases the 
+    mental overhead of programming with few compensating advantages. Why use a 
+    special purpose template language when the general purpose programming language 
+    you already know  does the job?<br />
+       </li>
+    <li>
+<strong>To use Python syntax, idiom, and patterns.</strong> The reason for this design goal is similar to the reason behind  goal number three: if a programmer 
+    has already invested the time to learn Python, why devalue that investment 
+    by introducing syntax, idioms, or patterns that are not &quot;Pythonic&quot; into Python templating?<br />
+      <br />
+             <em>webstring</em> uses Python syntax, idiom, and patterns exclusively. Template placeholders  are mapped to Python objects. These 
+    objects implement portions of Python's <a href="http://docs.python.org/lib/typesseq.html">sequence API</a> and support operations like 
+    access by position, concatenation, and repetition. They can also be manipulated 
+    like Python strings.
+    If a <em>webstring</em> operation has an exact analog in existing 
+    Python usage, the Python analog was used. Where no exact one-to-one analog 
+    exists, names of methods and attributes from the Python standard library and 
+    third-party modules where the usage approaches <em>webstring's</em> were used. <br />
+      <br />
+            Making 
+    methods as Pythonic as possible was a major emphasis of <em>webstring's</em> development. 
+    Use <em>webstring</em> should be painless for a Python programmer; its 
+    usage should be a direct and natural outgrowth of their previous Python experience.<br />
+    </li>
+    <li><strong>To play well with other Python software.</strong> <em>webstring</em> is designed to be imported into another piece of Python software 
+    and used without much modification or complexity. Its API is Pythonic and 
+    many of its operations use standard Python syntax. All data inputs into <em>webstring</em> 
+    use standard Python data structures like strings, lists, and dictionaries.<br />
+      <br />
+    <em>webstring</em> provides classes that implement the Python <a href="http://www.python.org/dev/peps/pep-0333/">Web Server Gateway 
+    Interface</a> (WSGI) standard that provides a common way for Python web applications 
+    to run on different web servers. These classes, WSGITemplate,  WSGIHTMLTemplate, 
+    and WSGITextTemplate, are WSGI middleware that allows WSGI-compliant Python web applications 
+    to dynamically output XML,  HTML, and text.<br />
+      <br />
+      <em>webstring </em>also includes a class, TurboWebstring, that implements the TurboGears/Buffet <a href="http://www.turbogears.org/docs/plugins/template.html">template plugin API</a>.</li>
+  </ol>
+	
+  <em>webstring's </em>XML and HTML templating was designed to meet the following goals:
+    
+  <ol>
+    <li><strong>To use XML as a data format, not a programming language.</strong> XML has several disadvantages as a programming language. First of all, it 
+    was never intended to be a programming language. Tim Berners-Lee, creator 
+    of HTML and a driving force behind the standardization of XML, commented on HTML and, by implication, on XML that, &quot;I chose HTML not to be a programming language because I wanted different 
+    programs to do different things with it: present it differently, extract tables 
+    of contents, index it, and so on.&quot; It  must also be structured in ways that, while useful for a data format, 
+    are unnecessarily verbose, restrictive, and repetitive for a programming language, 
+    especially if the programming language is Python. 
+      <p> XML is   also frequently worked on by non-programmers. Mixing logic  and XML may force non-programmers to acquire a programming awareness that may be counterproductive 
+    to their jobs. They  might also be forced to wait for a programmer to 
+    change the data format before they can work on it (and vice versa). <br />
+        <br />
+XML is for data. Python is for logic.</p>
+    </li>
+    <li><strong>To use existing XML formats.</strong> Many template engines use custom XML syntax for placeholders, usually either 
+    custom comments, elements, or attributes. Existing XML formats must often 
+    include this template engine specific XML to work with these template engines. 
+    This can violate the MVC advantages of clarity, modularity, and division of 
+    labor. It can make using outside software that provides special processing 
+    for a specific XML format more difficult. It can lead to template engine 
+    lock-in since prohibitively extensive modifications may be required to move 
+    an XML template from one template engine to another.<br />
+      <br />
+    <em>webstring</em> is designed to work with existing XML formats as they are. The only 
+    modifications to an XML document that <em>webstring</em> requires is assigning a unique 
+    identifier to each element used as a placeholder. <em>webstring</em> can use any XML 
+    attribute as a placeholder but, by default, it uses the ID attribute. This 
+    closely follows the spirit of the W3C <a href="http://www.w3.org/TR/xml-id/">xml:id</a> standard which makes the ID attribute 
+    the standard mechanism for uniquely identifying elements within an XML document.<br />
+       
+    </li>
+    <li><strong>To hide the parts of an XML document that are not being used.</strong> <em>
+    webstring</em>  uses a <a href="http://www.phpwact.org/pattern/template_view#component_apis">component API</a> style: it only exposes elements that 
+    are marked with a placeholder and usually only &quot;the elements in the template 
+    that need to be manipulated are marked&quot;. Each element marked with a placeholder 
+    can be accessed, evaluated, and manipulated separately. Elements and attributes 
+    that do not have a placeholder remain hidden and  do not exist from the programmer or application's perspective.<br />
+ </li>
+    <li>
+<strong>To use the best Python XML libraries.</strong> <a href="http://effbot.org/zone/celementtree.htm">cElementTree</a>  provides a high performance library with a highly Pythonic 
+    API for processing XML with Python. 
+    <a href="http://codespeak.net/lxml/">lxml</a> implements the same API as cElementTree 
+    but adds additional features. While cElementTree supports 
+    most of the XML 1.1 standard, XML namespaces, and parts of the XPath 1.0 standard, 
+    lxml, since it's a binding for the <a href="http://xmlsoft.org/">libxml2 and libxslt libraries</a>, supports 
+    those standards plus XSLT, XInclude, XML Schema, RelaxNG, Xpointer, and xml:id. 
+    Since libxml2 and libxslt are written in C, lxml's performance approaches 
+    that of cElementTree.<br />
+      <br />
+    <em>webstring</em> does not force its users to pick between best of breed Python XML 
+    processing libraries. They can use the library that best fits their needs 
+    while using the same simple yet powerful API.<br />
+    </li>
+    <li>To bridge HTML and XML.
+XML purists would like to leave HTML behind. But they can't. To quote the<a href="http://www.kid-templating.org/trac/wiki/KidFaq#but-isn-t-tag-soup-like-html-4-evil"> Kid FAQ</a>:
+      <blockquote>
+        <p><em>Q: But isn't tag-soup like HTML 4 evil?<br />
+    <br />
+    A: No. HTML 4.01 isn't XML but it's the best option for serving pages at present 
+    because all browsers have relatively strong support for it. Serving XHTML as text/html has serious issues and not all browsers (IE &lt;= 7.0) support XHTML as application/xhtml+xml. </em>
+        </p>
+        <p><em>However, maintaining content in an XML based format is advantageous because you can 
+    perform validation, transformations, and other stuff using readily available 
+    tools. It's possible to have the best of both worlds: HTML 4.01 for the browser 
+    and XHTML (or some custom XML format) for the server.</em></p>
+        <p><em>Some of us still believe 
+    that XHTML will eventually be supported well, and that when it does, it will 
+    be the way to go. You should be able to &quot;flip a switch, make it work&quot; 
+    when that day comes instead of doing a massive migration</em>.</p>
+      </blockquote>
+      <p> <em>webstring's</em> HTMLTemplate class handles these cases. It can take HTML, even 
+    if it is horribly broken, transform it into valid XHTML, and correctly output 
+    it as HTML 4.01, XHTML 1.0, or XHTML 1.1 following the standard and practice 
+    of the W3C.</p>
+    </li>
+  </ol
+    1. To separate model and view logic from controller logic. >
+</div>
+<div class="textheader"><a id="license">LICENSE</a></div>
+<div class="textblock"><em>webstring</em> is distributed under a <a href="http://www.opensource.org/licenses/bsd-license.php">BSD 
+  license</a>.</div>
+<div class="textheader"><a id="download">DOWNLOAD</a></div>
+<div class="textblock"> <em>webstring</em> is available from the <a href="http://cheeseshop.python.org/pypi/webstring/">CheeseShop</a> 
+  as a: 
+  <ul>
+    <li> Windows <a href="http://cheeseshop.python.org/packages/source/w/webstring/webstring-0.5.zip">source 
+      package</a> (zipfile)</li>
+    <li> Windows <a href="http://cheeseshop.python.org/packages/source/w/webstring/webstring-0.5.win32.exe">binary 
+      installer</a></li>
+    <li> UNIX <a href="http://cheeseshop.python.org/packages/source/w/webstring/webstring-0.5.tar.gz">source 
+      package</a> (gzipped tarball)</li>
+    <li>UNIX <a href="http://cheeseshop.python.org/packages/source/w/webstring/webstring-0.5.tar.bz2">source 
+      package</a> (bzipped tarball)</li>
+    <li><a href="http://cheeseshop.python.org/packages/2.4/w/webstring/webstring-0.5-py2.4.egg">Python 
+      2.4 Egg</a></li>
+    <li><a href="http://cheeseshop.python.org/packages/2.5/w/webstring/webstring-0.5-py2.5.egg">Python 
+      2.5 Egg</a></li>
+  </ul>
+  <em>webstring's</em> current release is 0.5 (1.4.2007). The change log for 0.5 
+  is available here: <a href="http://psilib.sourceforge.net/changelog-0.5">CHANGELOG-0.5</a>.<br />
+<br />
+  <em>lwebstring</em> was a standalone <a href="http://codespeak.net/lxml/">lxml</a>-based 
+  implementation of <em>webstring</em> available from the <a href="http://cheeseshop.python.org/pypi/lwebstring/">CheeseShop</a> 
+  as a:
+<ul>
+    <li> Windows <a href="http://cheeseshop.python.org/packages/source/l/lwebstring/lwebstring-0.5.zip">source 
+      package</a> (zipfile)</li>
+    <li> Windows <a href="http://cheeseshop.python.org/packages/2.4/l/lwebstring/lwebstring-0.5.win32.exe">binary 
+      installer</a></li>
+    <li> UNIX <a href="http://cheeseshop.python.org/packages/source/l/lwebstring/lwebstring-0.5.tar.gz">source 
+      package</a> (gzipped tarball)</li>
+    <li>UNIX <a href="http://cheeseshop.python.org/packages/source/l/lwebstring/lwebstring-0.5.tar.bz2">source 
+      package</a> (bzipped tarball)</li>
+    <li><a href="http://cheeseshop.python.org/packages/2.4/l/lwebstring/lwebstring-0.5-py2.4.egg">Python 
+      Egg</a></li>
+  </ul>
+  The last <em>lwebstring </em> release was 0.5 (10.5.2006). After this release, 
+  <em>lwebstring</em> was incorporated into <em>webstring</em> proper<em>. </em>The 
+  change log for <em>lwebstring</em> 0.5 is available here: <a href="http://psilib.sourceforge.net/CHANGELOG-lwebstring-0.5">CHANGELOG-lwebstring-0.5</a>.</div>
+<div class="textheader"><a id="installation">INSTALLATION</a></div>
+<div class="textblock">To install <em>webstring</em>  using <em><a href="http://peak.telecommunity.com/DevCenter/EasyInstall">easy_install</a>, </em>
+ run the following   command with administrative privileges:</div>
+<div class="codeblock"><pre>easy_install webstring</pre></div>
+<div class="textheader"><a id="requirements">REQUIREMENTS</a></div>
+<div class="textblock"><em>webstring</em> requires <a href="http://effbot.org/downloads/#cElementTree">cElementTree</a>, 
+    <a href="http://effbot.org/downloads/#elementtree">elementtree</a>, and <a href="http://codespeak.net/lxml/">lxml</a>. 
+    <em>webstring</em> can use either cElementTree or lxml as its XML processing 
+    library. Installing <em>webstring</em> with <em><a href="http://peak.telecommunity.com/DevCenter/EasyInstall">easy_install</a></em> 
+    automatically downloads and installs cElementTree, elementtree, and lxml if 
+    necessary along with <em>webstring</em>.<br />
+	<br />
+  <a href="http://effbot.org/downloads/#elementtidy">elementtidy</a> is required 
+    for <em>webstring's</em> <em>HTMLTemplate</em> class if you need to handle 
+    broken HTML with cElementTree.<br />
+    <br />
+    <em>webstring</em> has been tested and verified to work with <a href="http://www.python.org/download/releases/2.4/">Python 
+    2.4</a> and <a href="http://www.python.org/download/releases/2.5/">Python 
+    2.5</a>.</p>
+</div>
+<div class="textheader"><a id="classes">CLASSES</a></div>
+  
+<div class="textblock"><em>webstring</em> comes with the following specialized 
+  classes: 
+  <ul>
+    <li>XmlTemplate is a frontend for <em>webstring's</em> XML templating 
+      classes.</li>
+    <li>EtreeTemplate is an XML template class that uses cElementTree 
+      as its XML processing library.</li>
+    <li>LxmlTemplate is an XML template class that uses lxml as its XML 
+      processing library.</li>
+    <li>TextTemplate is a general purpose text templating class. A tutorial 
+      for <em>webstring's</em> text templating is available <a href="text.html">here</a>.</li>
+    <li>HTMLTemplate provides HTML templating plus HTML-specific tasks 
+      like cleaning up broken HTML and outputting correct (X)HTML.</li>
+  </ul>
+These classes can be used individually or accessed through <em>webstring's </em>Template 
+  class, which acts as a general purpose frontend to all of <em>webstring's</em> specialized 
+  classes. </div>
+<div class="codeblock"><pre>&gt;&gt;&gt; <span class="keyword">from</span> webstring <span class="keyword">import</span> Template</pre></div>
+<div class="textblock">The remaining examples in this document use <em>webstring's </em>XmlTemplate as the backend to Template. LxmlTemplate and EtreeTemplate 
+have minor differences in output. In LxmlTemplate, there is no space between the tag name and the closing /&gt; of a closed tag 
+(i.e. &lt;br/&gt; instead of &lt;br /&gt;) and in EtreeTemplate there is a space. Attribute order may also vary and namespaces may 
+be handled differently.</div>
+<div class="textheader"><a id="initialization">INITIALIZATION</a></div>
+<div class="textblock">A Template object can be initialized empty:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; exampleA = Template()</pre></div>
+<div class="textblock">From a file with the <em>fromfile</em> method:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; exampleB.fromfile(<span class="string">'example.rss'</span>)</pre></div>
+<div class="textblock">By passing the path to the file as the first argument to the class constructor:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; exampleC = Template(<span class="string">'example.rss'</span>)</pre></div>
+<div class="textblock">From a string with the <em>fromstring</em> method:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; exampleD = Template.fromstring(<span class="string">&quot;&quot;&quot;&lt;rss version=&quot;2.0&quot;&gt;</span><br />...  <span class="string">&lt;channel&gt;</span><br />...   <span class="string">&lt;title&gt;Example&lt;/title&gt;</span><br />...   <span class="string">&lt;link&gt;http://www.example.org/&lt;/link&gt;</span><br />...   <span class="string">&lt;description&gt;RSS Example&lt;/description&gt;</span><br />...   <span class="string">&lt;language&gt;en-us&lt;/language&gt;</span><br />...   <span class="string">&lt;pubDate id=&quot;cpubdate&quot;&gt;$month $day, $year&lt;/pubDate&gt;</span><br />...   <span class="string">&lt;lastBuildDate id=&quot;lastbuilddate&quot;&gt;%(month)s %(day)s, %(year)s&lt;/lastBuildDate&gt;</span>
+...   <span class="string">&lt;item class=&quot;item&quot;&gt;</span><br />...    <span class="string">&lt;title id=&quot;title&quot; /&gt;</span><br />...    <span class="string">&lt;link id=&quot;link&quot; /&gt;</span><br />...    <span class="string">&lt;guid id=&quot;guid&quot; isPermaLink=&quot;true&quot; /&gt;</span><br />...    <span class="string">&lt;description id=&quot;description&quot; /&gt;</span><br />...    <span class="string">&lt;pubDate id=&quot;ipubdate&quot; /&gt;</span><br />...   <span class="string">&lt;/item&gt;</span><br />...  <span class="string">&lt;/channel&gt;</span><br />...  <span class="string">&lt;/rss&gt;&quot;&quot;&quot;</span>)</pre></div>
+<div class="textblock">By passing a string as  the first argument  to the class constructor:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example = Template(<span class="string">&quot;&quot;&quot;&lt;rss version=&quot;2.0&quot;&gt;</span><br />...  <span class="string">&lt;channel&gt;</span><br />...   <span class="string">&lt;title&gt;Example&lt;/title&gt;</span><br />...   <span class="string">&lt;link&gt;http://www.example.org/&lt;/link&gt;</span><br />...   <span class="string">&lt;description&gt;RSS Example&lt;/description&gt;</span><br />...   <span class="string">&lt;language&gt;en-us&lt;/language&gt;</span><br />...   <span class="string">&lt;pubDate id=&quot;cpubdate&quot;&gt;$month $day, $year&lt;/pubDate&gt;</span><br />...   <span class="string">&lt;lastBuildDate id=&quot;lastbuilddate&quot;&gt;%(month)s %(day)s, %(year)s&lt;/lastBuildDate&gt;</span>
+...   <span class="string">&lt;item class=&quot;item&quot;&gt;</span><br />...    <span class="string">&lt;title id=&quot;title&quot; /&gt;</span><br />...    <span class="string">&lt;link id=&quot;link&quot; /&gt;</span><br />...    <span class="string">&lt;guid id=&quot;guid&quot; isPermaLink=&quot;true&quot; /&gt;</span><br />...    <span class="string">&lt;description id=&quot;description&quot; /&gt;</span><br />...    <span class="string">&lt;pubDate id=&quot;ipubdate&quot; /&gt;</span><br />...   <span class="string">&lt;/item&gt;</span><br />...  <span class="string">&lt;/channel&gt;</span><br />...  <span class="string">&lt;/rss&gt;&quot;&quot;&quot;</span>)</pre></div>
+<div class="textblock">The choice of whether to use lxml and <em>LxmlTemplate</em> 
+  or cElementTree and <em>EtreeTemplate</em> is controlled by using the <em>engine</em> 
+  keyword passed to the object constructor:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example = Template(engine="lxml")</pre></div>
+<div class="textblock">This selects <em>LxmlTemplate</em> and uses lxml as the 
+  XML processing library. LxmlTemplate and lxml support additional advanced XML 
+  features like <a href="http://www.w3.org/tr/xslt">XSLT</a> and <a href="http://www.w3.org/TR/xinclude/">XInclude</a> 
+  that EtreeTemplate and cElementTree do not.<br />
+  <br />
+  <em>HTMLTemplate</em> can be selected using the <em>format</em> keyword passed 
+  to the object constructor:</div>
+  <div class="codeblock"><pre>&gt;&gt;&gt; example = Template(format="html", engine="lxml")</pre></div>
+<div class="textblock"><em>HTMLTemplate</em> can also be told to use lxml as its HTML 
+  processing library by passing the <em>engine</em> keyword together with the 
+  <em>format</em> keyword to the object constructor:</div>
+    <div class="codeblock"><pre>&gt;&gt;&gt; example = Template(format="html", engine="lxml")</pre></div>	    
+<div class="textheader"><a id="objects">OBJECTS</a></div>
+<div class="textblock"><em>webstring</em>  automatically maps an XML document to a root object. Any XML element with an XML attribute (by default, <strong><a href="http://www.w3.org/TR/xml-id/">id</a></strong>)
+  that uniquely identifies it within an XML document is  mapped to a field object and attached to the  root object of its  parent document.</div>
+<div class="codeblock"><pre class="stdout">&lt;pubDate <span class="highlight">id=&quot;cpubdate&quot;</span>&gt;$month $day, $year&lt;/pubDate&gt;</pre></div>
+<div class="textblock">Groups of fields can be created  by assigning a parent element an attribute (by default, <strong>class</strong>) whose value   is a globally unique identifier  within an XML document.
+  <em>webstring</em>  then maps the parent element to a group object which is attached  to the root object of its parent document. Any child elements marked as fields within that parent element are mapped to field objects and  attached to the group object.<br />
+<br />
+Group objects cannot contain other group objects.</div>
+<div class="codeblock"><pre class="stdout">&lt;item <span class="highlight">class=&quot;item&quot;</span>&gt;<br /> &lt;title id=&quot;title&quot; /&gt;<br /> &lt;link id=&quot;link&quot; /&gt;<br /> &lt;guid id=&quot;guid&quot; isPermaLink=&quot;true&quot; /&gt;<br /> &lt;description id=&quot;description&quot; /&gt;<br /> &lt;pubDate id=&quot;ipubdate&quot; /&gt;<br />&lt;/item&gt;</pre></div>
+<div class="textblock">XML attributes of an element marked as a field are mapped to attribute objects and attached to that element's field
+    object.<br />
+<br />At maximum, a root's object hierarchy will never be more than four levels deep.<br /><br />Root level:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example<br /><span class="stdout">&lt;Template &quot;root&quot; at db7dd0&gt;</span></pre></div>
+<div class="textblock">Group level:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.item<br /><span class="stdout">&lt;Template &quot;item&quot; at f5d870&gt;</span></pre></div>
+<div class="textblock">Field level:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.item.guid<br /><span class="stdout">&lt;Template &quot;guid&quot; at f5da70&gt;</span></pre></div>
+<div class="textblock">Attribute level:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.item.guid.isPermaLink<br /><span class="stdout">'true'</span></pre></div>
+<div class="textblock">At minimum, a root object's depth will only be two levels deep.<br /><br />Root level:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example<br /><span class="stdout">&lt;Template &quot;root&quot; at db7dd0&gt;</span></pre></div>
+<div class="textblock">Field level:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.cpubdate<br /><span class="stdout">&lt;Template &quot;cpubdate&quot; at e7a350&gt;</span></pre></div>
+<div class="textblock">By default, all elements tagged as fields or groups become
+  part of a root's object hierarchy except for elements marked  as groups that have  no  child elements marked as fields. However,
+  existing fields or groups within an XML document can be excluded or included before or after a root is initialized by using its <em>exclude</em> or <em>include</em> methods.<br />
+  <br />
+  Exclusion with the <em>exclude</em> method:</div>
+  <div class="codeblock"><pre>&gt;&gt;&gt; example.exclude(<span class="string">'cpubdate'</span>, <span class="string">'guid'</span>) <br />&gt;&gt;&gt; <span class="keyword">print</span> example<br /><span class="stdout">&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  &lt;lastBuildDate id=&quot;lastbuilddate&quot;&gt;%(month)s %(day)s, %(year)s&lt;/lastBuildDate&gt;<br />  &lt;item class=&quot;item&quot;&gt;<br />   &lt;title id=&quot;title&quot; /&gt;<br />   &lt;link id=&quot;link&quot; /&gt;<br />   &lt;description id=&quot;description&quot; /&gt;<br />   &lt;pubDate id=&quot;ipubdate&quot; /&gt;<br />  &lt;/item&gt;<br /> &lt;/channel&gt;<br /> &lt;/rss&gt;</span></pre></div>
+<div class="textblock">Inclusion with the <em>include</em> method:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.include(<span class="string">'cpubdate'</span>, <span class="string">'guid'</span>)<br />&gt;&gt;&gt; <span class="keyword">print</span> example<br /><span class="stdout">&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  </span><span class="highlight">&lt;pubDate id=&quot;cpubdate&quot;&gt;$month $day, $year&lt;/pubDate&gt;</span><span class="stdout"><br />  &lt;lastBuildDate id=&quot;lastbuilddate&quot;&gt;%(month)s %(day)s, %(year)s&lt;/lastBuildDate&gt;
+  &lt;item class=&quot;item&quot;&gt;<br />   &lt;title id=&quot;title&quot; /&gt;<br />   &lt;link id=&quot;link&quot; /&gt;<br />   </span><span class="highlight">&lt;guid id=&quot;guid&quot; isPermaLink=&quot;true&quot; /&gt;</span><span class="stdout"><br />   &lt;description id=&quot;description&quot; /&gt;<br />   &lt;pubDate id=&quot;ipubdate&quot; /&gt;<br />  &lt;/item&gt;<br /> &lt;/channel&gt;<br /> &lt;/rss&gt;</span></pre></div>
+<div class="textblock">Fields and groups can  be removed by deleting
+  their object attribute:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; <span class="keyword">del</span> example.cpubdate<br />&gt;&gt;&gt; <span class="keyword">print</span> example<br /><span class="stdout">&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  &lt;lastBuildDate id=&quot;lastbuilddate&quot;&gt;%(month)s %(day)s, %(year)s&lt;/lastBuildDate&gt;<br />  &lt;item class=&quot;item&quot;&gt;<br />   &lt;title id=&quot;title&quot; /&gt;<br />   &lt;link id=&quot;link&quot; /&gt;<br />   &lt;guid id=&quot;guid&quot; isPermaLink=&quot;true&quot; /&gt;<br />   &lt;description id=&quot;description&quot; /&gt;<br />   &lt;pubDate id=&quot;ipubdate&quot; /&gt;<br />  &lt;/item&gt;<br /> &lt;/channel&gt;<br /> &lt;/rss&gt;</span></pre></div>
+<div class="textblock">A root, field, or group can be set back to its default state by calling
+  its <em>reset</em> method:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.reset()<br />&gt;&gt;&gt; <span class="keyword">print</span> example<br /><span class="stdout">&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  &lt;pubDate id=&quot;cpubdate&quot;&gt;$month $day, $year&lt;/pubDate&gt;<br />  &lt;lastBuildDate id=&quot;lastbuilddate&quot;&gt;%(month)s %(day)s, %(year)s&lt;/lastBuildDate&gt;<br />  &lt;item class=&quot;item&quot;&gt;<br />   &lt;title id=&quot;title&quot; /&gt;<br />   &lt;link id=&quot;link&quot; /&gt;<br />   &lt;guid id=&quot;guid&quot; isPermaLink=&quot;true&quot; /&gt;<br />   &lt;description id=&quot;description&quot; /&gt;<br />   &lt;pubDate id=&quot;ipubdate&quot; /&gt;<br />  &lt;/item&gt;<br /> &lt;/channel&gt;<br /> &lt;/rss&gt;</span></pre></div>
+<div class="textheader"><a id="dataaccess">ACCESS</a></div>
+<div class="textblock">Fields can be accessed by object attribute:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.cpubdate<br /><span class="stdout">&lt;Template &quot;cpubdate&quot; at e7a350&gt;</span></pre></div>
+<div class="textblock">By keyword:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example[<span class="string">'cpubdate'</span>]<br /><span class="stdout">&lt;Template &quot;cpubdate&quot; at e7a350&gt;</span></pre></div>
+<div class="textblock">By position:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example[<span class="int">0</span>]<br /><span class="stdout">&lt;Template &quot;cpubdate&quot; at e7a350&gt;</span></pre></div>
+<div class="textblock">Groups are accessed the same way:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.item <br /><span class="stdout">&lt;Template &quot;item&quot; at f5d870&gt;</span><br />&gt;&gt;&gt; example[<span class="string">'item'</span>]<br /><span class="stdout">&lt;Template &quot;item&quot; at f5d870&gt;</span><br />&gt;&gt;&gt; example[<span class="int">2</span>]<br /><span class="stdout">&lt;Template &quot;item&quot; at f5d870&gt;</span></pre></div>
+<div class="textblock">Fields within a group are accessed by combining its identifier and  its group identifier:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.item.title <br /><span class="stdout">&lt;Template &quot;title&quot; at f5d9b0&gt;</span><br />&gt;&gt;&gt; example[<span class="string">'item'</span>][<span class="string">'title'</span>]<br /><span class="stdout">&lt;Template &quot;title&quot; at f5d9b0&gt;</span><br />&gt;&gt;&gt; example[<span class="int">2</span>][<span class="int">0</span>]<br /><span class="stdout">&lt;Template &quot;title&quot; at f5d9b0&gt;</span></pre></div>
+<div class="textblock">Attributes can be accessed either by object attribute or by keyword:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.item.guid.isPermaLink<br /><span class="stdout">'true'</span><br />&gt;&gt;&gt; example[<span class="string">'item'</span>][<span class="string">'guid'</span>][<span class="string">'isPermaLink'</span>]<br /><span class="stdout">'true'</span></pre></div>
+<div class="textblock">By default, <em>webstring</em> automatically maps fields, groups, and attributes to object attributes with the same name as the field, group, or attribute's identifier. This &quot;auto-magical&quot; behavior can be disabled by passing a boolean value of <span class="keyword">False</span> to the class constructor  as the second argument when a Template or HTMLTemplate object is initialized:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; exampleZ = Template(<span class="string">'example.rss', </span><span class="keyword">False</span>)</pre></div>
+<div class="textblock">Fields, groups, and attributes can   then be accessed by keyword or  position  but not by named object attribute.</div>
+<div class="textheader"><a id="sub">SUBSTITUTION</a></div>
+<div class="textblock">Text can be substituted into a field by assigning a string to a field's text property:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.item.description.text = <span class="string">'Example of assigning text to a field.'</span>
+&gt;&gt;&gt; <span class="keyword">print</span> example<br /><span class="stdout">&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  &lt;pubDate id=&quot;cpubdate&quot;&gt;June 06, 2006&lt;/pubDate&gt;<br />  &lt;lastBuildDate id=&quot;lastbuilddate&quot;&gt;June 06, 2006&lt;/lastBuildDate&gt;<br />  &lt;item class=&quot;item&quot;&gt;<br />   &lt;title id=&quot;title&quot; /&gt;<br />   &lt;link id=&quot;link&quot; /&gt;<br />   &lt;guid id=&quot;guid&quot; isPermaLink=&quot;true&quot; /&gt;<br />   &lt;description id=&quot;description&quot;&gt;</span><span class="highlight">Example of assigning text to a field.</span><span class="stdout">&lt;/description&gt;<br />   &lt;pubDate id=&quot;ipubdate&quot; /&gt;<br />  &lt;/item&gt;<br />  &lt;/channel&gt;<br /> &lt;/rss&gt;</span></pre></div>
+<div class="textblock">Text can also be formatted by substituting text into a field's string template. There are two ways to assign a string template to a field.
+  The first way is to embed a string template directly in the XML source:</div>
+<div class="codeblock"><pre class="stdout">&lt;pubDate id=&quot;cpubdate&quot;&gt;<span class="highlight">$month $day, $year</span>&lt;/pubDate&gt;</pre></div>
+<div class="textblock">This string template follows the pattern used by Python's <a href="http://docs.python.org/lib/node109.html"><em>string.Template</em></a>
+  class where <strong>$</strong> identifies a location (e.g. <span class="highlight">$month</span>) where strings can be substituted into a template to make a new string. A field's
+  template is used to format its text when a dictionary of location identifier/substitute string pairs is assigned to its text property:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.cpubdate.text = {<span class="string">'month'</span>:<span class="string">'June'</span>, <span class="string">'day'</span>:<span class="string">'06'</span>, <span class="string">'year'</span>:<span class="string">'2006'</span>}<br />&gt;&gt;&gt; <span class="keyword">print</span> example<br /><span class="stdout">&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  &lt;pubDate id=&quot;cpubdate&quot;&gt;</span><span class="highlight">June 06, 2006</span><span class="stdout">&lt;/pubDate&gt;<br />  &lt;lastBuildDate id=&quot;lastbuilddate&quot;&gt;%(month)s %(day)s, %(year)s&lt;/lastBuildDate&gt;<br />  &lt;item class=&quot;item&quot;&gt;<br />   &lt;title id=&quot;title&quot; /&gt;<br />   &lt;link id=&quot;link&quot; /&gt;<br />   &lt;guid id=&quot;guid&quot; isPermaLink=&quot;true&quot; /&gt;<br />   &lt;description id=&quot;description&quot; /&gt;<br />   &lt;pubDate id=&quot;ipubdate&quot; /&gt;<br />  &lt;/item&gt;<br /> &lt;/channel&gt;<br /> &lt;/rss&gt;</span></pre></div>
+<div class="textblock"><em>lastbuilddate's</em> embedded string template follows a pattern used by Python's <a href="http://docs.python.org/lib/typesseq-strings.html">built-in string formatting</a> where <strong>%(<em>name</em>)s</strong> identifies locations
+  (e.g. <span class="highlight">%(month)s</span>) where strings can be substituted into a template to make a new string:</div>
+<div class="codeblock"><pre class="stdout">&lt;lastBuildDate id=&quot;lastbuilddate&quot;&gt;<span class="highlight">%(month)s %(day)s, %(year)s</span>&lt;/lastBuildDate&gt;</pre></div>
+<div class="textblock">String templates following this pattern are used exactly like string templates that follow the <em>string.Template</em> pattern:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.lastbuilddate.text = {<span class="string">'month'</span>:<span class="string">'June'</span>, <span class="string">'day'</span>:<span class="string">'06'</span>, <span class="string">'year'</span>:<span class="string">'2006'</span>}<br />&gt;&gt;&gt; <span class="keyword">print</span> example<br /><span class="stdout">&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  &lt;pubDate id=&quot;cpubdate&quot;&gt;June 06, 2006&lt;/pubDate&gt;<br />  &lt;lastBuildDate id=&quot;lastbuilddate&quot;&gt;</span><span class="highlight">June 06, 2006</span><span class="stdout">&lt;/lastBuildDate&gt;<br />  &lt;item class=&quot;item&quot;&gt;<br />   &lt;title id=&quot;title&quot; /&gt;<br />   &lt;link id=&quot;link&quot; /&gt;<br />   &lt;guid id=&quot;guid&quot; isPermaLink=&quot;true&quot; /&gt;<br />   &lt;description id=&quot;description&quot; /&gt;<br />   &lt;pubDate id=&quot;ipubdate&quot; /&gt;<br />  &lt;/item&gt;<br /> &lt;/channel&gt;<br /> &lt;/rss&gt;</span></pre></div>
+<div class="textblock">String templates embedded in an XML document are automatically assigned
+  to a field's <em>template</em> property:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.cpubdate.template<br /><span class="stdout">&lt;string.Template object at 0x00F81F70&gt;</span><br />&gt;&gt;&gt; example.lastbuilddate.template<br /><span class="stdout">%(month)s %(day)s, %(year)s</span></pre></div>
+<div class="textblock">The second way to assign a string template to a field
+  is to manually assign it to a field's <em>template</em> property:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.item.link.template = <span class="string">'http://www.example.org/rss/$id'</span><br />&gt;&gt;&gt; example.item.link.template<br /><span class="stdout">&lt;string.Template object at 0x00DB7E70&gt;</span><br />&gt;&gt;&gt; example.item.link.text = {<span class="string">'id'</span>:<span class="string">'5423093'</span>}<br />&gt;&gt;&gt; <span class="keyword">print</span> example<br /><span class="stdout">&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  &lt;pubDate id=&quot;cpubdate&quot;&gt;June 06, 2006&lt;/pubDate&gt;<br />  &lt;lastBuildDate id=&quot;lastbuilddate&quot;&gt;June 06, 2006&lt;/lastBuildDate&gt;<br />  &lt;item class=&quot;item&quot;&gt;<br />   &lt;title id=&quot;title&quot; /&gt;<br />   &lt;link id=&quot;link&quot;&gt;</span><span class="highlight">http://www.example.org/rss/5423093</span><span class="stdout">&lt;/link&gt;<br />   &lt;guid id=&quot;guid&quot; isPermaLink=&quot;true&quot; /&gt;<br />   &lt;description id=&quot;description&quot;&gt;Example of assigning text to a field.&lt;/description&gt;<br />   &lt;pubDate id=&quot;ipubdate&quot; /&gt;<br />  &lt;/item&gt;<br /> &lt;/channel&gt;<br /> &lt;/rss&gt;</span></pre></div>
+<div class="textblock">String templates can be assigned to multiple fields in one operation  by using a root or group's <em>templates</em> method:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.item.templates({<span class="string">'title'</span>:{<span class="string">'text'</span>:<span class="string">'Example Title: $content'</span>},
+... <span class="string">'ipubdate'</span>:{<span class="string">'text'</span>:<span class="string">'$month $day, $year'</span>}})<br />&gt;&gt;&gt; example.item.title.template<br /><span class="stdout">&lt;string.Template object at 0x00EA75B0&gt;</span><br />&gt;&gt;&gt; example.item.ipubdate.template<br /><span class="stdout">&lt;string.Template object at 0x00EA7690&gt;</span><br />&gt;&gt;&gt; example.item.title.text = {<span class="string">'content'</span>:<span class="string">'First Example'</span>}<br />&gt;&gt;&gt; example.item.ipubdate.text = {<span class="string">'month'</span>:<span class="string">'June'</span>, <span class="string">'day'</span>:<span class="string">'6'</span>, <span class="string">'year'</span>:<span class="string">'2006'</span>}<br />&gt;&gt;&gt; <span class="keyword">print</span> example<br /><span class="stdout">&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  &lt;pubDate id=&quot;cpubdate&quot;&gt;June 06, 2006&lt;/pubDate&gt;<br />  &lt;lastBuildDate id=&quot;lastbuilddate&quot;&gt;June 06, 2006&lt;/lastBuildDate&gt;<br />  &lt;item class=&quot;item&quot;&gt;<br />   &lt;title id=&quot;title&quot;&gt;</span><span class="highlight">Example Title: First Example</span><span class="stdout">&lt;/title&gt;<br />   &lt;link id=&quot;link&quot;&gt;http://www.example.org/rss/5423093&lt;/link&gt;<br />   &lt;guid id=&quot;guid&quot; isPermaLink=&quot;true&quot; /&gt;<br />   &lt;description id=&quot;description&quot;&gt;Example of assigning text to a field.&lt;/description&gt;<br />   &lt;pubDate id=&quot;ipubdate&quot;&gt;</span><span class="highlight">June 6, 2006</span><span class="stdout">&lt;/pubDate&gt;<br />  &lt;/item&gt;<br /> &lt;/channel&gt;<br /> &lt;/rss&gt;</span></pre></div>
+<div class="textheader"><a id="attr">ATTRIBUTES</a></div>
+<div class="textblock">The value of an XML attribute can be set by assigning a string to its object attribute:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.item.guid.isPermaLink = <span class="string">'false'</span><br />&gt;&gt;&gt; <span class="keyword">print</span> example<br /><span class="stdout">&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  &lt;pubDate id=&quot;cpubdate&quot;&gt;June 06, 2006&lt;/pubDate&gt;<br />  &lt;lastBuildDate id=&quot;lastbuilddate&quot;&gt;June 06, 2006&lt;/lastBuildDate&gt;<br />  &lt;item class=&quot;item&quot;&gt;<br />   &lt;title id=&quot;title&quot;&gt;Example Title: First Example&lt;/title&gt;<br />   &lt;link id=&quot;link&quot;&gt;http://www.example.org/rss/5423093&lt;/link&gt;<br />   &lt;guid id=&quot;guid&quot; isPermaLink=</span><span class="highlight">&quot;false&quot;</span><span class="stdout"> /&gt;<br />   &lt;description id=&quot;description&quot;&gt;Example of assigning text to a field.&lt;/description&gt;<br />   &lt;pubDate id=&quot;ipubdate&quot;&gt;June 6, 2006&lt;/pubDate&gt;<br />  &lt;/item&gt;<br /> &lt;/channel&gt;<br /> &lt;/rss&gt;</span></pre></div>
+<div class="textblock">One or more existing  attribute values can be changed or one or more new  attributes  added using a field's <em>update</em> method:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.item.guid.update({<span class="string">'isPermaLink'</span>:<span class="string">'true'</span>, <span class="string">'id'</span>:<span class="string">'GUID'</span>,
+... <span class="string">'{http://www.w3.org/1999/02/22-rdf-syntax-ns#}resource'</span>:<span class="string">'http://www.example.org/rss/5423093'</span>})<br />&gt;&gt;&gt; <span class="keyword">print</span> example<br /><span class="stdout">&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  &lt;pubDate id=&quot;cpubdate&quot;&gt;June 06, 2006&lt;/pubDate&gt;<br />  &lt;lastBuildDate id=&quot;lastbuilddate&quot;&gt;June 06, 2006&lt;/lastBuildDate&gt;<br />  &lt;item class=&quot;item&quot;&gt;<br />   &lt;title id=&quot;title&quot;&gt;Example Title: First Example&lt;/title&gt;<br />   &lt;link id=&quot;link&quot;&gt;http://www.example.org/rss/5423093&lt;/link&gt;<br />   &lt;guid </span><span class="highlight">id=&quot;GUID&quot;</span><span class="stdout"> </span><span class="highlight">isPermaLink=&quot;true&quot; rdf:resource=&quot;http://www.example.org/rss/5423093&quot;</span><span class="stdout"> xmlns:rdf=&quot;http://www.w3.org/1999/02/22-rdf-syntax-ns#&quot; /&gt;<br />   &lt;description id=&quot;description&quot;&gt;Example of assigning text to a field.&lt;/description&gt;<br />   &lt;pubDate id=&quot;ipubdate&quot;&gt;June 6, 2006&lt;/pubDate&gt;<br />  &lt;/item&gt;<br /> &lt;/channel&gt;<br /> &lt;/rss&gt;</span></pre></div>
+<div class="textblock">One or more string templates for formatting attribute values can be set by assigning a dictionary of attribute name/attribute template pairs to a field's <em>atemplates</em> property:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.item.guid.atemplates = {
+... '<span class="string">{http://www.w3.org/1999/02/22-rdf-syntax-ns#}resource'</span>:<span class="string">'http://www.example.org/rss/$guid'</span>}</pre></div>
+<div class="textblock">The attribute value is then  formatted by the attribute's template  when a dictionary
+  of attribute name/dictionary pairs is passed to the attribute either with the <em>update</em> method:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.item.guid.update({
+... <span class="string">'{http://www.w3.org/1999/02/22-rdf-syntax-ns#}resource'</span>:{<span class="string">'guid':'5423094'</span>}})</pre></div>
+<div class="textblock">or by assigning a dictionary of attribute name/dictionary pairs directly to its  object attribute:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.item.guid.resource = {<span class="string">'guid'</span>:<span class="string">'5423093'</span>}<br />&gt;&gt;&gt; <span class="keyword">print</span> example<br /><span class="stdout">&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  &lt;pubDate id=&quot;cpubdate&quot;&gt;June 06, 2006&lt;/pubDate&gt;<br />  &lt;lastBuildDate id=&quot;lastbuilddate&quot;&gt;June 06, 2006&lt;/lastBuildDate&gt;<br />  &lt;item class=&quot;item&quot;&gt;<br />   &lt;title id=&quot;title&quot;&gt;Example Title: First Example&lt;/title&gt;<br />   &lt;link id=&quot;link&quot;&gt;http://www.example.org/rss/5423093&lt;/link&gt;<br />   &lt;guid id=&quot;GUID&quot; isPermaLink=&quot;true&quot; </span><span class="highlight">rdf:resource=&quot;http://www.example.org/rss/5423093&quot;</span><span class="stdout"> xmlns:rdf=&quot;http://www.w3.org/1999/02/22-rdf-syntax-ns#&quot; /&gt;<br />   &lt;description id=&quot;description&quot;&gt;Example of assigning text to a field.&lt;/description&gt;<br />   &lt;pubDate id=&quot;ipubdate&quot;&gt;June 6, 2006&lt;/pubDate&gt;<br />  &lt;/item&gt;<br /> &lt;/channel&gt;<br /> &lt;/rss&gt;</span></pre></div>
+<div class="textblock">One or more attributes can be removed by using a field's <em>purge</em> method:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.item.guid.purge(<span class="string">'{http://www.w3.org/1999/02/22-rdf-syntax-ns#}resource'</span>)<br />&gt;&gt;&gt; <span class="keyword">print</span> example<br /><span class="stdout">&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  &lt;pubDate id=&quot;cpubdate&quot;&gt;June 06, 2006&lt;/pubDate&gt;<br />  &lt;lastBuildDate id=&quot;lastbuilddate&quot;&gt;June 06, 2006&lt;/lastBuildDate&gt;<br />  &lt;item class=&quot;item&quot;&gt;<br />   &lt;title id=&quot;title&quot;&gt;Example Title: First Example&lt;/title&gt;<br />   &lt;link id=&quot;link&quot;&gt;http://www.example.org/rss/5423093&lt;/link&gt;<br />   &lt;guid id=&quot;GUID&quot; isPermaLink=&quot;true&quot; /&gt;<br />   &lt;description id=&quot;description&quot;&gt;Example of assigning text to a field.&lt;/description&gt;<br />   &lt;pubDate id=&quot;ipubdate&quot;&gt;June 6, 2006&lt;/pubDate&gt;<br />  &lt;/item&gt;<br /> &lt;/channel&gt;<br /> &lt;/rss&gt;</span></pre></div>
+<div class="textblock">An attribute can also be removed by deleting its object attribute:</div>
+<div class="codeblock">
+<pre>&gt;&gt;&gt; example.item.guid.update(
+... {<span class="string">'{http://www.w3.org/1999/02/22-rdf-syntax-ns#}resource'</span>:<span class="string">'http://www.example.org/rss/5423093'</span>})<br />&gt;&gt;&gt; <span class="keyword">del</span> example.item.guid.resource<br />&gt;&gt;&gt; <span class="keyword">print</span> example<br /><span class="stdout">&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  &lt;pubDate id=&quot;cpubdate&quot;&gt;June 06, 2006&lt;/pubDate&gt;<br />  &lt;lastBuildDate id=&quot;lastbuilddate&quot;&gt;June 06, 2006&lt;/lastBuildDate&gt;<br />  &lt;item class=&quot;item&quot;&gt;<br />   &lt;title id=&quot;title&quot;&gt;Example Title: First Example&lt;/title&gt;<br />   &lt;link id=&quot;link&quot;&gt;http://www.example.org/rss/5423093&lt;/link&gt;<br />   &lt;guid id=&quot;guid&quot; isPermaLink=&quot;false&quot; /&gt;<br />   &lt;description id=&quot;description&quot;&gt;Example of assigning text to a field.&lt;/description&gt;<br />   &lt;pubDate id=&quot;ipubdate&quot;&gt;June 6, 2006&lt;/pubDate&gt;<br />  &lt;/item&gt;<br /> &lt;/channel&gt;<br /> &lt;/rss&gt;</span></pre></div>
+<div class="textheader"><a id="batch">BATCH SUBSTITUTION</a></div>
+<div class="textblock">The modulo operator can be used to assign templates and substitute text into  elements and attributes in one batch substitution.
+  Using the modulo operator without the assignment operator (<strong>%</strong>) creates a new object. Using the modulo operator with the assignment operator (<strong>%=</strong>) modifies the left-hand object. <br />
+<br />In a batch substitution, text substitutions are given the keyword <span class="string">'text'</span> and passed in a dictionary to a field:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.reset()<br />&gt;&gt;&gt; example.cpubdate %= {<span class="string">'text'</span>:{<span class="string">'month'</span>:<span class="string">'June'</span>, <span class="string">'day'</span>:<span class="string">'06'</span>, <span class="string">'year'</span>:<span class="string">'2006'</span>}}<br />&gt;&gt;&gt; example.lastbuilddate %= {<span class="string">'text'</span>:{<span class="string">'month'</span>:<span class="string">'June'</span>, <span class="string">'day'</span>:<span class="string">'06'</span>, <span class="string">'year'</span>:<span class="string">'2006'</span>}}</pre></div>
+<div class="textblock">Template assignments are identified by the keyword <span class="string">'templates'</span> and text substitutions are identified by the keyword
+  <span class="string">'subs'</span>:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.item %= {<br />... <span class="string">'templates'</span>:{<br />...     <span class="string">'title'</span>:{<span class="string">'text'</span>:<span class="string">'Example Title: $content'</span>},<br />...     <span class="string">'ipubdate'</span>:{<span class="string">'text'</span>:<span class="string">'$month $day, $year'</span>},<br />...     <span class="string">'link'</span>:{<span class="string">'text'</span>:<span class="string">'http://www.example.org/rss/$id'</span>}},<br />... <span class="string">'subs'</span>:((<br />...     {<span class="string">'text'</span>:{<span class="string">'content'</span>:<span class="string">'First Example'</span>}},<br />...     {<span class="string">'text'</span>:{<span class="string">'id'</span>:<span class="string">'5423093'</span>}}, {<span class="string">'attrib'</span>:{<span class="string">'id'</span>:<span class="string">'GUID'</span>}},<br />...     {<span class="string">'text'</span>:<span class="string">'http://www.example.org/rss/5423093'</span>},<br />...     <span class="string">'Example of assigning text to a field.'</span>,<br />...     {<span class="string">'text'</span>:{<span class="string">'month'</span>:<span class="string">'June'</span>, <span class="string">'day'</span>:<span class="string">'6'</span>, <span class="string">'year'</span>:<span class="string">'2006'</span>}}),)}<br />&gt;&gt;&gt; <span class="keyword">print</span> example<br /><span class="stdout">&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  &lt;pubDate id=&quot;cpubdate&quot;&gt;June 06, 2006&lt;/pubDate&gt;<br />  &lt;lastBuildDate id=&quot;lastbuilddate&quot;&gt;June 06, 2006&lt;/lastBuildDate&gt;<br />  &lt;item class=&quot;item&quot;&gt;<br />   &lt;title id=&quot;title&quot;&gt;</span><span class="highlight">Example Title: First Example</span><span class="stdout">&lt;/title&gt;<br />   &lt;link id=&quot;link&quot;&gt;</span><span class="highlight">http://www.example.org/rss/5423093</span><span class="stdout">&lt;/link&gt;<br />   &lt;guid id=&quot;GUID&quot; isPermaLink=&quot;true&quot;&gt;</span><span class="highlight">http://www.example.org/rss/5423093</span><span class="stdout">&lt;/guid&gt;<br />   &lt;description id=&quot;description&quot;&gt;</span><span class="highlight">Example of assigning text to a field.</span><span class="stdout">&lt;/description&gt;<br />   &lt;pubDate id=&quot;ipubdate&quot;&gt;</span><span class="highlight">June 6, 2006</span><span class="stdout">&lt;/pubDate&gt;<br />  &lt;/item&gt;<br /> &lt;/channel&gt;<br /> &lt;/rss&gt;</span></pre></div>
+<div class="textblock">Templates are stored in a dictionary under the name of the field they are assigned to (e.g. <span class="string">'title'</span>). This
+  dictionary can contain any number of templates up to but not exceeding the number of fields in the root or group to which it is passed. Text templates are string templates that are stored under the keyword <span class="string">'text'</span>.
+  Attribute templates, stored under the keyword <span class="string">'attrib'</span>, are a dictionary of pairs consisting of an attribute name and a string template . <br />
+  <br />
+  Substitutions are stored in a tuple. The number of items in a substitution's tuple must be equal to the number of fields in the root or group to which it is passed. Each
+  item in  a substitution's tuple can be a string or a dictionary of substitutions. Within a dictionary of substitutions, the keyword <span class="string">'text'</span>
+  identifies text substitutions, the value of which can be either a string or a dictionary of text template substitutions, and the keyword <span class="string">'attrib'</span> identifies attribute substitutions, the value of which is a dictionary
+  containing pairs of attribute names and  strings or  dictionaries of attribute template substitutions. All tuples containing substitutions are put in another tuple and stored under the <span class="string">'subs'</span>
+  keyword.<br />
+  <br />
+  The modulo operator can also substitute a dictionary containing pairs of field names and substitutions into every field or group in a root object in one operation:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example %= {<br />... <span class="string">'cpubdate'</span>:{<span class="string">'text'</span>:{<span class="string">'month'</span>:<span class="string">'June'</span>, <span class="string">'day'</span>:<span class="string">'06'</span>, <span class="string">'year'</span>:<span class="string">'2006'</span>}}, <br />... <span class="string">'lastbuilddate'</span>:{<span class="string">'text'</span>:{<span class="string">'month'</span>:<span class="string">'June'</span>, <span class="string">'day'</span>:<span class="string">'06'</span>, <span class="string">'year'</span>:<span class="string">'2006'</span>}},<br />... <span class="string">'item'</span>:{<span class="string">'templates'</span>:{<span class="string">'title'</span>:{<span class="string">'text'</span>:<span class="string">'Example Title: $content'</span>},
+... 	<span class="string">'ipubdate'</span>:{<span class="string">'text'</span>:<span class="string">'$month $day, $year'</span>},<br />... 	<span class="string">'link'</span>:{<span class="string">'text'</span>:<span class="string">'http://www.example.org/rss/$id'</span>}},<br />... 	<span class="string">'title'</span>:{<span class="string">'text'</span>:{<span class="string">'content'</span>:<span class="string">'First Example'</span>}},<br />... 	<span class="string">'link'</span>:{<span class="string">'text'</span>:{<span class="string">'id'</span>:<span class="string">'5423093'</span>}},<br />... 	<span class="string">'guid'</span>:{<span class="string">'attrib'</span>:{<span class="string">'id'</span>:<span class="string">'GUID'</span>}, <span class="string">'text'</span>:<span class="string">'http://www.example.org/rss/5423093'</span>},<br />... 	<span class="string">'description'</span>:{<span class="string">'text'</span>:<span class="string">'Example of assigning text to a field.'</span>},<br />... 	<span class="string">'ipubdate'</span>:{<span class="string">'text'</span>:{<span class="string">'month'</span>:<span class="string">'June'</span>, <span class="string">'day'</span>:<span class="string">'6'</span>, <span class="string">'year'</span>:<span class="string">'2006'</span>}}}}<br />&gt;&gt;&gt; <span class="keyword">print</span> example<br /><span class="stdout">&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  &lt;pubDate id=&quot;cpubdate&quot;&gt;</span><span class="highlight">June 06, 2006</span><span class="stdout">&lt;/pubDate&gt;<br />  &lt;lastBuildDate id=&quot;lastbuilddate&quot;&gt;</span><span class="highlight">June 06, 2006</span><span class="stdout">&lt;/lastBuildDate&gt;<br />  &lt;item class=&quot;item&quot;&gt;<br />   &lt;title id=&quot;title&quot;&gt;</span><span class="highlight">Example Title: First Example</span><span class="stdout">&lt;/title&gt;<br />   &lt;link id=&quot;link&quot;&gt;</span><span class="highlight">http://www.example.org/rss/5423093</span><span class="stdout">&lt;/link&gt;<br />   &lt;guid id=</span><span class="highlight">&quot;GUID&quot;</span><span class="stdout"> isPermaLink=&quot;true&quot;&gt;</span><span class="highlight">http://www.example.org/rss/5423093</span><span class="stdout">&lt;/guid&gt;<br />   &lt;description id=&quot;description&quot;&gt;</span><span class="highlight">Example of assigning text to a field.</span><span class="stdout">&lt;/description&gt;<br />   &lt;pubDate id=&quot;ipubdate&quot;&gt;</span><span class="highlight">June 06, 2006</span><span class="stdout">&lt;/pubDate&gt;<br />  &lt;/item&gt;<br /> &lt;/channel&gt;<br /> &lt;/rss&gt;</span></pre></div>
+<div class="textheader"><a id="state">STATE</a></div>
+<div class="textblock">Each root, field, or group has a <em>current</em> and a <em>default</em> property. The <em>current</em> property returns the object's current state:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.current<br /><span class="stdout">&lt;Template &quot;root&quot; at dcd290&gt;</span><br />&gt;&gt;&gt; <span class="keyword">print</span> example.current<br /><span class="stdout">&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  &lt;pubDate id=&quot;cpubdate&quot;&gt;June 06, 2006&lt;/pubDate&gt;<br />  &lt;lastBuildDate id=&quot;lastbuilddate&quot;&gt;June 06, 2006&lt;/lastBuildDate&gt;<br />  &lt;item class=&quot;item&quot;&gt;<br />   &lt;title id=&quot;title&quot;&gt;Example Title: First Example&lt;/title&gt;<br />   &lt;link id=&quot;link&quot;&gt;http://www.example.org/rss/5423093&lt;/link&gt;<br />   &lt;guid id=&quot;GUID&quot; isPermaLink=&quot;true&quot;&gt;http://www.example.org/rss/5423093&lt;/guid&gt;<br />   &lt;description id=&quot;description&quot;&gt;Example of assigning text to a field.&lt;/description&gt;<br />   &lt;pubDate id=&quot;ipubdate&quot;&gt;June 6, 2006&lt;/pubDate&gt;<br />  &lt;/item&gt;<br /> &lt;/channel&gt;<br /> &lt;/rss&gt;</span></pre></div>
+<div class="textblock">The <em>default</em> property returns the object's
+  default state:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.default<br /><span class="stdout">&lt;Template &quot;root&quot; at f62d10&gt;</span><br />&gt;&gt;&gt; <span class="keyword">print</span> example.default<br /><span class="stdout">&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  &lt;pubDate id=&quot;cpubdate&quot;&gt;$month $day, $year&lt;/pubDate&gt;<br />  &lt;lastBuildDate id=&quot;lastbuilddate&quot;&gt;%(month)s %(day)s, %(year)s&lt;/lastBuildDate&gt;<br />  &lt;item class=&quot;item&quot;&gt;<br />   &lt;title id=&quot;title&quot; /&gt;<br />   &lt;link id=&quot;link&quot; /&gt;<br />   &lt;guid id=&quot;guid&quot; isPermaLink=&quot;true&quot; /&gt;<br />   &lt;description id=&quot;description&quot; /&gt;<br />   &lt;pubDate id=&quot;ipubdate&quot; /&gt;<br />  &lt;/item&gt;<br /> &lt;/channel&gt;<br /> &lt;/rss&gt;</span></pre></div>
+<div class="textheader"><a id="add">CONCATENATION</a></div>
+<div class="textblock">Roots, fields, and groups can be concatenated together using the addition operator.<br /><br />Roots:</div>
+<div class="codeblock">
+<pre>&gt;&gt;&gt; example.reset()<br />&gt;&gt;&gt; <span class="keyword">print</span> example + example<br /><span class="stdout">&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  &lt;pubDate id=&quot;cpubdate&quot;&gt;$month $day, $year&lt;/pubDate&gt;<br />  &lt;lastBuildDate id=&quot;lastbuilddate&quot;&gt;%(month)s %(day)s, %(year)s&lt;/lastBuildDate&gt;<br />  &lt;item class=&quot;item&quot;&gt;<br />   &lt;title id=&quot;title&quot; /&gt;<br />   &lt;link id=&quot;link&quot; /&gt;<br />   &lt;guid id=&quot;guid&quot; isPermaLink=&quot;true&quot; /&gt;<br />   &lt;description id=&quot;description&quot; /&gt;<br />   &lt;pubDate id=&quot;ipubdate&quot; /&gt;<br />  &lt;/item&gt;<br /> &lt;/channel&gt;<br /> </span><span class="highlight">&lt;rss version=&quot;2.0&quot;&gt;
+ &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  &lt;pubDate id=&quot;cpubdate&quot;&gt;$month $day, $year&lt;/pubDate&gt;<br />  &lt;lastBuildDate id=&quot;lastbuilddate&quot;&gt;%(month)s %(day)s, %(year)s&lt;/lastBuildDate&gt;<br />  &lt;item class=&quot;item&quot;&gt;<br />   &lt;title id=&quot;title&quot; /&gt;<br />   &lt;link id=&quot;link&quot; /&gt;<br />   &lt;guid id=&quot;guid&quot; isPermaLink=&quot;true&quot; /&gt;<br />   &lt;description id=&quot;description&quot; /&gt;<br />   &lt;pubDate id=&quot;ipubdate&quot; /&gt;<br />  &lt;/item&gt;<br /> &lt;/channel&gt;
+ &lt;/rss&gt;</span><span class="stdout">&lt;/rss&gt;</span></pre></div>
+<div class="textblock">Groups:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; <span class="keyword">print</span> example.item + example.item<br /><span class="stdout">&lt;item class=&quot;item&quot;&gt;<br />   &lt;title id=&quot;title&quot; /&gt;<br />   &lt;link id=&quot;link&quot; /&gt;<br />   &lt;guid id=&quot;guid&quot; isPermaLink=&quot;true&quot; /&gt;<br />   &lt;description id=&quot;description&quot; /&gt;<br />   &lt;pubDate id=&quot;ipubdate&quot; /&gt;<br />  &lt;/item&gt;<br /> </span><span class="highlight">&lt;item class=&quot;item&quot;&gt;<br />   &lt;title id=&quot;title&quot; /&gt;<br />   &lt;link id=&quot;link&quot; /&gt;<br />   &lt;guid id=&quot;guid&quot; isPermaLink=&quot;true&quot; /&gt;<br />   &lt;description id=&quot;description&quot; /&gt;<br />   &lt;pubDate id=&quot;ipubdate&quot; /&gt;<br />  &lt;/item&gt;</span></pre></div>
+<div class="textblock">Fields:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; <span class="keyword">print</span> example.item.title + example.item.title<br /><span class="stdout">&lt;title id=&quot;title&quot; /&gt;<br /> </span><span class="highlight">&lt;title id=&quot;title&quot; /&gt;</span></pre></div>
+<div class="textblock">Using the addition operator (<strong>+</strong>) without the assignment operator (<strong>=</strong>) results in a new object. Using
+  the addition and assignment operators together (<strong>+=</strong>) modifies the left-hand object:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.item += example.item<br />&gt;&gt;&gt; <span class="keyword">print</span> example<br /><span class="stdout">&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  &lt;pubDate id=&quot;cpubdate&quot;&gt;$month $day, $year&lt;/pubDate&gt;<br />  &lt;lastBuildDate id=&quot;lastbuilddate&quot;&gt;%(month)s %(day)s, %(year)s&lt;/lastBuildDate&gt;<br />  &lt;item class=&quot;item&quot;&gt;<br />   &lt;title id=&quot;title&quot; /&gt;<br />   &lt;link id=&quot;link&quot; /&gt;<br />   &lt;guid id=&quot;guid&quot; isPermaLink=&quot;true&quot; /&gt;<br />   &lt;description id=&quot;description&quot; /&gt;<br />   &lt;pubDate id=&quot;ipubdate&quot; /&gt;<br />  &lt;/item&gt;<br /> </span><span class="highlight">&lt;item class=&quot;item&quot;&gt;<br />   &lt;title id=&quot;title&quot; /&gt;<br />   &lt;link id=&quot;link&quot; /&gt;<br />   &lt;guid id=&quot;guid&quot; isPermaLink=&quot;true&quot; /&gt;<br />   &lt;description id=&quot;description&quot; /&gt;<br />   &lt;pubDate id=&quot;ipubdate&quot; /&gt;<br />  &lt;/item&gt;</span><span class="stdout"><br /> &lt;/channel&gt;<br /> &lt;/rss&gt;</span></pre></div>
+<div class="textheader"><a id="mul">REPETITION</a></div>
+<div class="textblock">A root, group, or field can be repeated once by calling its <em>repeat</em> method:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.reset()<br />&gt;&gt;&gt; example.item.repeat()<br />&gt;&gt;&gt; <span class="keyword">print</span> example<br /><span class="stdout">&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  &lt;pubDate id=&quot;cpubdate&quot;&gt;$month $day, $year&lt;/pubDate&gt;<br />  &lt;lastBuildDate id=&quot;lastbuilddate&quot;&gt;%(month)s %(day)s, %(year)s&lt;/lastBuildDate&gt;<br />  &lt;item class=&quot;item&quot;&gt;<br />   &lt;title id=&quot;title&quot; /&gt;<br />   &lt;link id=&quot;link&quot; /&gt;<br />   &lt;guid id=&quot;guid&quot; isPermaLink=&quot;true&quot; /&gt;<br />   &lt;description id=&quot;description&quot; /&gt;<br />   &lt;pubDate id=&quot;ipubdate&quot; /&gt;<br />  &lt;/item&gt;
+</span><span class="highlight">&lt;item class=&quot;item&quot;&gt;<br />   &lt;title id=&quot;title&quot; /&gt;<br />   &lt;link id=&quot;link&quot; /&gt;<br />   &lt;guid id=&quot;guid&quot; isPermaLink=&quot;true&quot; /&gt;<br />   &lt;description id=&quot;description&quot; /&gt;<br />   &lt;pubDate id=&quot;ipubdate&quot; /&gt;<br />  &lt;/item&gt;</span><span class="stdout"><br /> &lt;/channel&gt;</span><span class="highlight"><br /></span><span class="stdout"> &lt;/rss&gt;</span></pre></div>
+<div class="textblock">A root, group, or field can be repeated more than once by using the multiplication operator, either by itself (<strong>*</strong>),
+  which returns a new object, or along with the assignment operator (<strong>*=</strong>), which modifies the left-hand object:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.reset()<br />&gt;&gt;&gt; example.item *= <span class="int">2</span><br />&gt;&gt;&gt; <span class="keyword">print</span> example<br /><span class="stdout">&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  &lt;pubDate id=&quot;cpubdate&quot;&gt;$month $day, $year&lt;/pubDate&gt;<br />  &lt;lastBuildDate id=&quot;lastbuilddate&quot;&gt;%(month)s %(day)s, %(year)s&lt;/lastBuildDate&gt;<br />  &lt;item class=&quot;item&quot;&gt;<br />   &lt;title id=&quot;title&quot; /&gt;<br />   &lt;link id=&quot;link&quot; /&gt;<br />   &lt;guid id=&quot;guid&quot; isPermaLink=&quot;true&quot; /&gt;<br />   &lt;description id=&quot;description&quot; /&gt;<br />   &lt;pubDate id=&quot;ipubdate&quot; /&gt;<br />  &lt;/item&gt;<br /> </span><span class="highlight">&lt;item class=&quot;item&quot;&gt;<br />   &lt;title id=&quot;title&quot; /&gt;<br />   &lt;link id=&quot;link&quot; /&gt;<br />   &lt;guid id=&quot;guid&quot; isPermaLink=&quot;true&quot; /&gt;<br />   &lt;description id=&quot;description&quot; /&gt;<br />   &lt;pubDate id=&quot;ipubdate&quot; /&gt;<br />  &lt;/item&gt;</span><span class="stdout"><br /> &lt;/channel&gt;<br /> &lt;/rss&gt;</span></pre></div>
+<div class="textblock">A root, field, or group can be repeated and have text substituted into it by passing a string, tuple, or dictionary to its <em>repeat</em>
+  method:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.reset()<br />&gt;&gt;&gt; example.item %= (
+... <span class="string">'Example Title: First Example'</span>,
+... <span class="string">'http://www.example.org/rss/5423092'</span>,
+... <span class="string">'http://www.example.org/rss/5423092'</span>,
+... <span class="string">'Example of assigning text to a field.'</span>,
+... <span class="string">'June 06, 2006'</span>)<br />&gt;&gt;&gt; example.item.repeat((
+... <span class="string">'Example Title: Second Example'</span>,
+... <span class="string">'http://www.example.org/rss/5423093'</span>,
+... <span class="string">'http://www.example.org/rss/5423093'</span>,
+... <span class="string">'Example of group repetition.'</span>,
+... <span class="string">'June 06, 2006'</span>))<br />&gt;&gt;&gt; <span class="keyword">print</span> example<br /><span class="stdout">&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  &lt;pubDate id=&quot;cpubdate&quot;&gt;$month $day, $year&lt;/pubDate&gt;<br />  &lt;lastBuildDate id=&quot;lastbuilddate&quot;&gt;%(month)s %(day)s, %(year)s&lt;/lastBuildDate&gt;<br />  &lt;item class=&quot;item&quot;&gt;<br />   &lt;title id=&quot;title&quot;&gt;</span><span class="highlight">Example Title: First Example</span><span class="stdout">&lt;/title&gt;<br />   &lt;link id=&quot;link&quot;&gt;</span><span class="highlight">http://www.example.org/rss/5423092</span><span class="stdout">&lt;/link&gt;<br />   &lt;guid id=&quot;guid&quot; isPermaLink=&quot;true&quot;&gt;</span><span class="highlight">http://www.example.org/rss/5423092</span><span class="stdout">&lt;/guid&gt;<br />   &lt;description id=&quot;description&quot;&gt;</span><span class="highlight">Example of assigning text to a field.</span><span class="stdout">&lt;/description&gt;<br />   &lt;pubDate id=&quot;ipubdate&quot;&gt;</span><span class="highlight">June 06, 2006</span><span class="stdout">&lt;/pubDate&gt;<br />  &lt;/item&gt;<br /> </span><span class="highlight">&lt;item class=&quot;item&quot;&gt;<br />   &lt;title id=&quot;title&quot;&gt;Example Title: Second Example&lt;/title&gt;<br />   &lt;link id=&quot;link&quot;&gt;http://www.example.org/rss/5423093&lt;/link&gt;<br />   &lt;guid id=&quot;guid&quot; isPermaLink=&quot;true&quot;&gt;http://www.example.org/rss/5423093&lt;/guid&gt;<br />   &lt;description id=&quot;description&quot;&gt;Example of group repetition.&lt;/description&gt;<br />   &lt;pubDate id=&quot;ipubdate&quot;&gt;June 06, 2006&lt;/pubDate&gt;<br />  &lt;/item&gt;</span><span class="stdout"><br /> &lt;/channel&gt;<br /> &lt;/rss&gt;</span></pre></div>
+<div class="textblock">A root, field, or group can be expanded to fit a sequence of substitutions by using the power operator (<strong>**</strong>) either alone,
+  which returns a new object, or joined with the assignment operator (<strong>**=</strong>), which modifies the left-hand object:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.reset()<br />&gt;&gt;&gt; example.item **= ((
+... <span class="string">'Example Title: First Example'</span>,
+... <span class="string">'http://www.example.org/rss/5423092'</span>,
+... <span class="string">'http://www.example.org/rss/5423092'</span>,
+... <span class="string">'Example of assigning text to a field.'</span>,
+... <span class="string">'June 06, 2006'</span>), (
+... <span class="string">'Example Title: Second Example'</span>,
+... <span class="string">'http://www.example.org/rss/5423093'</span>,
+... <span class="string">'http://www.example.org/rss/5423093'</span>,
+... <span class="string">'Example of group repetition.'</span>,
+... <span class="string">'June 06, 2006'</span>))<br />&gt;&gt;&gt; <span class="keyword">print</span> example<br /><span class="stdout">&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  &lt;pubDate id=&quot;cpubdate&quot;&gt;$month $day, $year&lt;/pubDate&gt;<br />  &lt;lastBuildDate id=&quot;lastbuilddate&quot;&gt;%(month)s %(day)s, %(year)s&lt;/lastBuildDate&gt;<br />  &lt;item class=&quot;item&quot;&gt;<br />   &lt;title id=&quot;title&quot;&gt;</span><span class="highlight">Example Title: First Example</span><span class="stdout">&lt;/title&gt;<br />   &lt;link id=&quot;link&quot;&gt;</span><span class="highlight">http://www.example.org/rss/5423092</span><span class="stdout">&lt;/link&gt;<br />   &lt;guid id=&quot;guid&quot; isPermaLink=&quot;true&quot;&gt;</span><span class="highlight">http://www.example.org/rss/5423092</span><span class="stdout">&lt;/guid&gt;<br />   &lt;description id=&quot;description&quot;&gt;</span><span class="highlight">Example of assigning text to a field.</span><span class="stdout">&lt;/description&gt;<br />   &lt;pubDate id=&quot;ipubdate&quot;&gt;</span><span class="highlight">June 06, 2006</span><span class="stdout">&lt;/pubDate&gt;<br />  &lt;/item&gt;<br /> </span><span class="highlight">&lt;item class=&quot;item&quot;&gt;<br />   &lt;title id=&quot;title&quot;&gt;Example Title: Second Example&lt;/title&gt;<br />   &lt;link id=&quot;link&quot;&gt;http://www.example.org/rss/5423093&lt;/link&gt;<br />   &lt;guid id=&quot;guid&quot; isPermaLink=&quot;true&quot;&gt;http://www.example.org/rss/5423093&lt;/guid&gt;<br />   &lt;description id=&quot;description&quot;&gt;Example of group repetition.&lt;/description&gt;<br />   &lt;pubDate id=&quot;ipubdate&quot;&gt;June 06, 2006&lt;/pubDate&gt;<br />  &lt;/item&gt;</span><span class="stdout"><br /> &lt;/channel&gt;<br /> &lt;/rss&gt;</span></pre></div>
+<div class="textblock">Expansion can be combined with  template assignment into a single batch substitution using the modulo operator:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.reset()<br />&gt;&gt;&gt; example.item %= {
+...	<span class="string">'templates'</span>:{
+...		<span class="string">'title'</span>:{<span class="string">'text'</span>:<span class="string">'Example Title: $content'</span>},
+...		<span class="string">'ipubdate'</span>:{<span class="string">'text'</span>:<span class="string">'$month $day, $year'</span>},
+...		<span class="string">'link'</span>:{<span class="string">'text'</span>:<span class="string">'http://www.example.org/rss/$id'</span>}},<br />... 	<span class="string">'subs'</span>:(
+...		({<span class="string">'text'</span>:{<span class="string">'content'</span>:<span class="string">'First Example'</span>}},
+... 			{<span class="string">'text'</span>:{<span class="string">'id'</span>:<span class="string">'5423092'</span>}},
+... 		<span class="string">	'http://www.example.org/rss/5423092'</span>,<br />... 		<span class="string">	'Example of assigning text to a field.'</span>,
+... 			{<span class="string">'text'</span>:{<span class="string">'year'</span>:<span class="string">'June'</span>, <span class="string">'day'</span>:<span class="string">'06'</span>, <span class="string">'year'</span>:<span class="string">'2006'</span>}}),<br />... 		({<span class="string">'text'</span>:{<span class="string">'content'</span>:<span class="string">'Second Example'</span>}},
+... 			{<span class="string">'text'</span>:{<span class="string">'id'</span>:<span class="string">'5423093'</span>}},
+... <span class="string">			'http://www.example.org/rss/5423093'</span>,<br />... <span class="string">			'Example of group repetition.'</span>,
+... 			{<span class="string">'text'</span>:{<span class="string">'month'</span>:<span class="string">'June'</span>, <span class="string">'day'</span>:<span class="string">'06'</span>, <span class="string">'year'</span>:<span class="string">'2006'</span>}}))}<br />&gt;&gt;&gt; <span class="keyword">print</span> example<br /><span class="stdout">&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  &lt;pubDate id=&quot;cpubdate&quot;&gt;$month $day, $year&lt;/pubDate&gt;<br />  &lt;lastBuildDate id=&quot;lastbuilddate&quot;&gt;%(month)s %(day)s, %(year)s&lt;/lastBuildDate&gt;<br />  &lt;item class=&quot;item&quot;&gt;<br />   &lt;title id=&quot;title&quot;&gt;</span><span class="highlight">Example Title: First Example</span><span class="stdout">&lt;/title&gt;<br />   &lt;link id=&quot;link&quot;&gt;</span><span class="highlight">http://www.example.org/rss/5423092</span><span class="stdout">&lt;/link&gt;<br />   &lt;guid id=&quot;guid&quot; isPermaLink=&quot;true&quot;&gt;</span><span class="highlight">http://www.example.org/rss/5423092</span><span class="stdout">&lt;/guid&gt;<br />   &lt;description id=&quot;description&quot;&gt;</span><span class="highlight">Example of assigning text to a field.</span><span class="stdout">&lt;/description&gt;<br />   &lt;pubDate id=&quot;ipubdate&quot;&gt;</span><span class="highlight">June 06, 2006</span><span class="stdout">&lt;/pubDate&gt;<br />  &lt;/item&gt;<br /> </span><span class="highlight">&lt;item class=&quot;item&quot;&gt;<br />   &lt;title id=&quot;title&quot;&gt;Example Title: Second Example&lt;/title&gt;<br />   &lt;link id=&quot;link&quot;&gt;http://www.example.org/rss/5423093&lt;/link&gt;<br />   &lt;guid id=&quot;guid&quot; isPermaLink=&quot;true&quot;&gt;http://www.example.org/rss/5423093&lt;/guid&gt;<br />   &lt;description id=&quot;description&quot;&gt;Example of group repetition.&lt;/description&gt;<br />   &lt;pubDate id=&quot;ipubdate&quot;&gt;June 06, 2006&lt;/pubDate&gt;<br />  &lt;/item&gt;</span><span class="stdout"><br /> &lt;/channel&gt;<br /> &lt;/rss&gt;</span></pre></div>
+<div class="textblock">The number of items in each tuple of substitutions must be equal to the number of fields in the root or group to which it is passed. These
+tuples are grouped together in another tuple and stored in the dictionary under the keyword <span class="string">'subs'</span>.<br />
+<br />
+  The maximum number of repetitions  that can be performed on a root, field, or group is controlled by the <em>max</em> property. Assigning a new
+  maximum number of repetitions to the <em>max</em> property assigns the same number to a root or group's child fields or groups. The default value of the <em>max</em>
+  property is 25. Exceeding the maximum repetition value assigned to the <em>max</em> property triggers an exception:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.reset()<br />&gt;&gt;&gt; example.max = <span class="int">1</span><br />&gt;&gt;&gt; example.item %= {
+...	<span class="string">'templates'</span>:{
+...		<span class="string">'title'</span>:{<span class="string">'text'</span>:<span class="string">'Example Title: $content'</span>},
+...		<span class="string">'ipubdate'</span>:{<span class="string">'text'</span>:<span class="string">'$month $day, $year'</span>},
+...		<span class="string">'link'</span>:{<span class="string">'text'</span>:<span class="string">'http://www.example.org/rss/$id'</span>}},<br />... 	<span class="string">'subs'</span>:(
+...		({<span class="string">'text'</span>:{<span class="string">'content'</span>:<span class="string">'First Example'</span>}},
+... 			{<span class="string">'text'</span>:{<span class="string">'id'</span>:<span class="string">'5423092'</span>}},
+... 		<span class="string">	'http://www.example.org/rss/5423092'</span>,<br />... 		<span class="string">	'Example of assigning text to a field.'</span>,
+... 			{<span class="string">'text'</span>:{<span class="string">'year'</span>:<span class="string">'June'</span>, <span class="string">'day'</span>:<span class="string">'06'</span>, <span class="string">'year'</span>:<span class="string">'2006'</span>}}),<br />... 		({<span class="string">'text'</span>:{<span class="string">'content'</span>:<span class="string">'Second Example'</span>}},
+... 			{<span class="string">'text'</span>:{<span class="string">'id'</span>:<span class="string">'5423093'</span>}},
+... <span class="string">			'http://www.example.org/rss/5423093'</span>,<br />... <span class="string">			'Example of group repetition.'</span>,
+... 			{<span class="string">'text'</span>:{<span class="string">'month'</span>:<span class="string">'June'</span>, <span class="string">'day'</span>:<span class="string">'06'</span>, <span class="string">'year'</span>:<span class="string">'2006'</span>}}))}<br /><span class="highlight">Traceback (most recent call last):<br />  File &quot;&lt;interactive input&gt;&quot;, line 1, in ?<br />  File &quot;webstring.py&quot;, line 641, in __imod__<br />    self.__ipow__(data.pop('subs'))<br />  File &quot;webstring.py&quot;, line 276, in __ipow__<br />    raise TypeError(_exceptions[0])<br />TypeError: maximum allowed repetitions exceeded</span></pre></div>
+<div class="textblock">Setting the <em>max</em> property back to a number greater that 1 allows the operation to be completed successfully:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.reset()<br />&gt;&gt;&gt; example.max = 1<br />&gt;&gt;&gt; example.item %= {
+...	<span class="string">'templates'</span>:{
+...		<span class="string">'title'</span>:{<span class="string">'text'</span>:<span class="string">'Example Title: $content'</span>},
+...		<span class="string">'ipubdate'</span>:{<span class="string">'text'</span>:<span class="string">'$month $day, $year'</span>},
+...		<span class="string">'link'</span>:{<span class="string">'text'</span>:<span class="string">'http://www.example.org/rss/$id'</span>}},<br />... 	<span class="string">'subs'</span>:(
+...		({<span class="string">'text'</span>:{<span class="string">'content'</span>:<span class="string">'First Example'</span>}},
+... 			{<span class="string">'text'</span>:{<span class="string">'id'</span>:<span class="string">'5423092'</span>}},
+... 		<span class="string">	'http://www.example.org/rss/5423092'</span>,<br />... 		<span class="string">	'Example of assigning text to a field.'</span>,
+... 			{<span class="string">'text'</span>:{<span class="string">'year'</span>:<span class="string">'June'</span>, <span class="string">'day'</span>:<span class="string">'06'</span>, <span class="string">'year'</span>:<span class="string">'2006'</span>}}),<br />... 		({<span class="string">'text'</span>:{<span class="string">'content'</span>:<span class="string">'Second Example'</span>}},
+... 			{<span class="string">'text'</span>:{<span class="string">'id'</span>:<span class="string">'5423093'</span>}},
+... <span class="string">			'http://www.example.org/rss/5423093'</span>,<br />... <span class="string">			'Example of group repetition.'</span>,
+... 			{<span class="string">'text'</span>:{<span class="string">'month'</span>:<span class="string">'June'</span>, <span class="string">'day'</span>:<span class="string">'06'</span>, <span class="string">'year'</span>:<span class="string">'2006'</span>}}))}<br /><span class="highlight"></span>&gt;&gt;&gt;</pre></div>
+<div class="textheader"><a id="append">APPENDING</a></div>
+<div class="textblock">Other Template objects can be appended  to a root, field, or group using its <em>append</em> method:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.reset()<br />&gt;&gt;&gt; example.cpubdate %= {<span class="string">'text'</span>:{<span class="string">'month'</span>:<span class="string">'June'</span>, <span class="string">'day'</span>:<span class="string">'06'</span>, <span class="string">'year'</span>:<span class="string">'2006'</span>}}<br />&gt;&gt;&gt; example.lastbuilddate %= {<span class="string">'text'</span>:{<span class="string">'month'</span>:<span class="string">'June'</span>, <span class="string">'day'</span>:<span class="string">'06'</span>, <span class="string">'year'</span>:<span class="string">'2006'</span>}}<br />&gt;&gt;&gt; example.item %= {
+...	<span class="string">'templates'</span>:{
+...		<span class="string">'title'</span>:{<span class="string">'text'</span>:<span class="string">'Example Title: $content'</span>},
+...		<span class="string">'ipubdate'</span>:{<span class="string">'text'</span>:<span class="string">'$month $day, $year'</span>},
+...		<span class="string">'link'</span>:{<span class="string">'text'</span>:<span class="string">'http://www.example.org/rss/$id'</span>}},<br />... 	<span class="string">'subs'</span>:(
+...		({<span class="string">'text'</span>:{<span class="string">'content'</span>:<span class="string">'First Example'</span>}},
+... 			{<span class="string">'text'</span>:{<span class="string">'id'</span>:<span class="string">'5423092'</span>}},
+... 		<span class="string">	'http://www.example.org/rss/5423092'</span>,<br />... 		<span class="string">	'Example of assigning text to a field.'</span>,
+... 			{<span class="string">'text'</span>:{<span class="string">'year'</span>:<span class="string">'June'</span>, <span class="string">'day'</span>:<span class="string">'06'</span>, <span class="string">'year'</span>:<span class="string">'2006'</span>}}),<br />... 		({<span class="string">'text'</span>:{<span class="string">'content'</span>:<span class="string">'Second Example'</span>}},
+... 			{<span class="string">'text'</span>:{<span class="string">'id'</span>:<span class="string">'5423093'</span>}},
+... <span class="string">			'http://www.example.org/rss/5423093'</span>,<br />... <span class="string">			'Example of group repetition.'</span>,
+... 			{<span class="string">'text'</span>:{<span class="string">'month'</span>:<span class="string">'June'</span>, <span class="string">'day'</span>:<span class="string">'06'</span>, <span class="string">'year'</span>:<span class="string">'2006'</span>}}))}<br /><span class="highlight"></span>&gt;&gt;&gt; example.item.description.append(Template(
+... '<span class="string">&lt;html&gt;&lt;head&gt;&lt;title&gt;Example&lt;/title&gt;&lt;/head&gt;&lt;body&gt;&lt;p&gt;Paragraph&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;'</span>))<br />&gt;&gt;&gt; <span class="keyword">del</span> example.item.description.text<br />&gt;&gt;&gt; <span class="keyword">print</span> example<br /><span class="stdout">&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  &lt;pubDate id=&quot;cpubdate&quot;&gt;June 06, 2006&lt;/pubDate&gt;<br />  &lt;lastBuildDate id=&quot;lastbuilddate&quot;&gt;June 06, 2006&lt;/lastBuildDate&gt;<br />  &lt;item class=&quot;item&quot;&gt;<br />   &lt;title id=&quot;title&quot;&gt;Example Title: First Example&lt;/title&gt;<br />   &lt;link id=&quot;link&quot;&gt;http://www.example.org/rss/5423092&lt;/link&gt;<br />   &lt;guid id=&quot;guid&quot; isPermaLink=&quot;true&quot;&gt;http://www.example.org/rss/5423092&lt;/guid&gt;<br />   &lt;description id=&quot;description&quot;&gt;</span><span class="highlight">&lt;html&gt;&lt;head&gt;&lt;title&gt;Example&lt;/title&gt;&lt;/head&gt;&lt;body&gt;&lt;p&gt;Paragraph&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</span><span class="stdout">&lt;/description&gt;<br />   &lt;pubDate id=&quot;ipubdate&quot;&gt;June 06, 2006&lt;/pubDate&gt;<br />  &lt;/item&gt;<br /> &lt;item class=&quot;item&quot;&gt;<br />   &lt;title id=&quot;title&quot;&gt;Example Title: Second Example&lt;/title&gt;<br />   &lt;link id=&quot;link&quot;&gt;http://www.example.org/rss/5423093&lt;/link&gt;<br />   &lt;guid id=&quot;guid&quot; isPermaLink=&quot;true&quot;&gt;http://www.example.org/rss/5423093&lt;/guid&gt;<br />   &lt;description id=&quot;description&quot;&gt;Example of group repetition.&lt;/description&gt;<br />   &lt;pubDate id=&quot;ipubdate&quot;&gt;June 06, 2006&lt;/pubDate&gt;<br />  &lt;/item&gt;<br /> &lt;/channel&gt;<br /> &lt;/rss&gt;</span></pre></div>
+<div class="textheader"><a id="iter">ITERATION</a></div>
+<div class="textblock">Performing a loop operation on a root or group iterates over  its    fields or groups in sequence:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; <span class="keyword">for</span> field <span class="keyword">in</span> example: field.__repr__()<br />... <br /><span class="stdout">'&lt;Template &quot;cpubdate&quot; at f62f50&gt;'<br />'&lt;Template &quot;lastbuilddate&quot; at e7a350&gt;'<br />'&lt;Template &quot;item&quot; at f627f0&gt;'</span></pre></div>
+<div class="textblock">Performing a loop operation on a field iterates over  its    attributes.</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; <span class="keyword">for</span> attr <span class="keyword">in</span> example.item.guid: <span class="keyword">print</span> attr.__repr__()<br />... <br /><span class="stdout">'isPermaLink'<br />'id'</span></pre></div>
+<div class="textheader"><a id="out">OUTPUT</a></div>
+<div class="textblock">Identifier attributes for  fields can be removed by deleting a root, field, or group's <em>mark</em> property. This operation  also deletes  field identifier attributes from any child fields or groups:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; <span class="keyword">del</span> example.mark<br />&gt;&gt;&gt; <span class="keyword">print</span> example<br /><span class="stdout">&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  &lt;pubDate&gt;June 06, 2006&lt;/pubDate&gt;<br />  &lt;lastBuildDate&gt;June 06, 2006&lt;/lastBuildDate&gt;<br />  &lt;item class=&quot;item&quot;&gt;<br />   &lt;title&gt;Example Title: First Example&lt;/title&gt;<br />   &lt;link&gt;http://www.example.org/rss/5423092&lt;/link&gt;<br />   &lt;guid isPermaLink=&quot;true&quot;&gt;http://www.example.org/rss/5423092&lt;/guid&gt;<br />   &lt;description&gt;&lt;html&gt;&lt;head&gt;&lt;title&gt;Example&lt;/title&gt;&lt;/head&gt;&lt;body&gt;&lt;p&gt;Paragraph&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;&lt;/description&gt;<br />   &lt;pubDate&gt;June 06, 2006&lt;/pubDate&gt;<br />  &lt;/item&gt;<br /> &lt;item class=&quot;item&quot;&gt;<br />   &lt;title&gt;Example Title: Second Example&lt;/title&gt;<br />   &lt;link&gt;http://www.example.org/rss/5423093&lt;/link&gt;<br />   &lt;guid isPermaLink=&quot;true&quot;&gt;http://www.example.org/rss/5423093&lt;/guid&gt;<br />   &lt;description&gt;Example of group repetition.&lt;/description&gt;<br />   &lt;pubDate&gt;June 06, 2006&lt;/pubDate&gt;<br />  &lt;/item&gt;<br /> &lt;/channel&gt;<br /> &lt;/rss&gt;</span></pre></div>
+<div class="textblock">Deleting the <em>groupmark</em> property deletes  all group identifier attributes:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; <span class="keyword">del</span> example.groupmark<br />&gt;&gt;&gt; <span class="keyword">print</span> example<br /><span class="stdout">&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  &lt;pubDate&gt;June 06, 2006&lt;/pubDate&gt;<br />  &lt;lastBuildDate&gt;June 06, 2006&lt;/lastBuildDate&gt;<br />  &lt;item&gt;<br />   &lt;title&gt;Example Title: First Example&lt;/title&gt;<br />   &lt;link&gt;http://www.example.org/rss/5423092&lt;/link&gt;<br />   &lt;guid isPermaLink=&quot;true&quot;&gt;http://www.example.org/rss/5423092&lt;/guid&gt;<br />   &lt;description&gt;&lt;html&gt;&lt;head&gt;&lt;title&gt;Example&lt;/title&gt;&lt;/head&gt;&lt;body&gt;&lt;p&gt;Paragraph&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;&lt;/description&gt;<br />   &lt;pubDate&gt;June 06, 2006&lt;/pubDate&gt;<br />  &lt;/item&gt;<br /> &lt;item&gt;<br />   &lt;title&gt;Example Title: Second Example&lt;/title&gt;<br />   &lt;link&gt;http://www.example.org/rss/5423093&lt;/link&gt;<br />   &lt;guid isPermaLink=&quot;true&quot;&gt;http://www.example.org/rss/5423093&lt;/guid&gt;<br />   &lt;description&gt;Example of group repetition.&lt;/description&gt;<br />   &lt;pubDate&gt;June 06, 2006&lt;/pubDate&gt;<br />  &lt;/item&gt;<br /> &lt;/channel&gt;<br /> &lt;/rss&gt;</span></pre></div>
+<div class="textblock">The <em>render</em> method is called to output an XML document as a string:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; <span class="keyword">print</span> example.render()<br /><span class="stdout">&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  &lt;pubDate&gt;June 06, 2006&lt;/pubDate&gt;<br />  &lt;lastBuildDate&gt;June 06, 2006&lt;/lastBuildDate&gt;<br />  &lt;item&gt;<br />   &lt;title&gt;Example Title: First Example&lt;/title&gt;<br />   &lt;link&gt;http://www.example.org/rss/5423092&lt;/link&gt;<br />   &lt;guid isPermaLink=&quot;true&quot;&gt;http://www.example.org/rss/5423092&lt;/guid&gt;<br />   &lt;description&gt;&lt;html&gt;&lt;head&gt;&lt;title&gt;Example&lt;/title&gt;&lt;/head&gt;&lt;body&gt;&lt;p&gt;Paragraph&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;&lt;/description&gt;<br />   &lt;pubDate&gt;June 06, 2006&lt;/pubDate&gt;<br />  &lt;/item&gt;<br /> &lt;item&gt;<br />   &lt;title&gt;Example Title: Second Example&lt;/title&gt;<br />   &lt;link&gt;http://www.example.org/rss/5423093&lt;/link&gt;<br />   &lt;guid isPermaLink=&quot;true&quot;&gt;http://www.example.org/rss/5423093&lt;/guid&gt;<br />   &lt;description&gt;Example of group repetition.&lt;/description&gt;<br />   &lt;pubDate&gt;June 06, 2006&lt;/pubDate&gt;<br />  &lt;/item&gt;<br /> &lt;/channel&gt;<br /> &lt;/rss&gt;</span></pre></div>
+<div class="textblock">The <em>write</em> method is called to write an XML document to a file:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; example.write(<span class="string">'finalexample.rss'</span>)</pre></div>
+<div class="textblock">The <em>pipe</em> method  outputs  an XML document as a string and resets it back to its default state:</div>
+<div class="codeblock"><pre>&gt;&gt;&gt; <span class="keyword">print</span> example.pipe()<br /><span class="stdout">&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  &lt;pubDate&gt;June 06, 2006&lt;/pubDate&gt;<br />  &lt;lastBuildDate&gt;June 06, 2006&lt;/lastBuildDate&gt;<br />  &lt;item&gt;<br />   &lt;title&gt;Example Title: First Example&lt;/title&gt;<br />   &lt;link&gt;http://www.example.org/rss/5423092&lt;/link&gt;<br />   &lt;guid isPermaLink=&quot;true&quot;&gt;http://www.example.org/rss/5423092&lt;/guid&gt;<br />   &lt;description&gt;&lt;html&gt;&lt;head&gt;&lt;title&gt;Example&lt;/title&gt;&lt;/head&gt;&lt;body&gt;&lt;p&gt;Paragraph&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;&lt;/description&gt;<br />   &lt;pubDate&gt;June 06, 2006&lt;/pubDate&gt;<br />  &lt;/item&gt;<br /> &lt;item&gt;<br />   &lt;title&gt;Example Title: Second Example&lt;/title&gt;<br />   &lt;link&gt;http://www.example.org/rss/5423093&lt;/link&gt;<br />   &lt;guid isPermaLink=&quot;true&quot;&gt;http://www.example.org/rss/5423093&lt;/guid&gt;<br />   &lt;description&gt;Example of group repetition.&lt;/description&gt;<br />   &lt;pubDate&gt;June 06, 2006&lt;/pubDate&gt;<br />  &lt;/item&gt;<br /> &lt;/channel&gt;<br /> &lt;/rss&gt;</span><br />&gt;&gt;&gt; <span class="keyword">print</span> example<span class="stdout"><br />&lt;rss version=&quot;2.0&quot;&gt;<br /> &lt;channel&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />  &lt;link&gt;http://www.example.org/&lt;/link&gt;<br />  &lt;description&gt;RSS Example&lt;/description&gt;<br />  &lt;language&gt;en-us&lt;/language&gt;<br />  &lt;pubDate id=&quot;cpubdate&quot;&gt;$month $day, $year&lt;/pubDate&gt;<br />  &lt;lastBuildDate id=&quot;lastbuilddate&quot;&gt;%(month)s %(day)s, %(year)s&lt;/lastBuildDate&gt;<br />  &lt;item class=&quot;item&quot;&gt;<br />   &lt;title id=&quot;title&quot; /&gt;<br />   &lt;link id=&quot;link&quot; /&gt;<br />   &lt;guid id=&quot;guid&quot; isPermaLink=&quot;true&quot; /&gt;<br />   &lt;description id=&quot;description&quot; /&gt;<br />   &lt;pubDate id=&quot;ipubdate&quot; /&gt;<br />  &lt;/item&gt;<br /> &lt;/channel&gt;<br /> &lt;/rss&gt;</span></pre></div>
+<div class="textheader"><a id="dev">DEVELOPMENT</a></div>
+<div class="textblock">Send <em>webstring</em> feature requests, patches, and bug reports to (email address
+  imaged and scrambled for spam-protection):<br />
+<img src="seceaddr.gif" width="500" height="100" alt="Contact"/></div>
+<p>
+<a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-xhtml11" alt="Valid XHTML 1.1" height="31" width="88" /></a>
+</p>
+<div class="footer">Copyright 2006 L. C. Rees. All rights reserved.</div>
+</body>
+</html>

File docs_requirements.txt

+sphinx
+sphinxcontrib.spelling
+lxml>=1.1.1
+stuf>=0.8.14
+'''webstring fabfile'''
+
+from fabric.api import prompt, local, settings, env, lcd
+
+
+def _test(val):
+    truth = val in ['py26', 'py27', 'py32']
+    if truth is False:
+        raise KeyError(val)
+    return val
+
+
+def tox():
+    '''test webstring'''
+    local('tox')
+
+
+def docs():
+    with lcd('./docs/'):
+        local('make clean')
+        local('make html')
+        local('make linkcheck')
+        local('make doctest')
+
+
+def update_docs():
+    docs()
+    with settings(warn_only=True):
+        local('hg ci -m docmerge; hg push')
+    local('./setup.py upload_sphinx')
+
+
+def tox_recreate():
+    '''recreate webstring test env'''
+    prompt(
+        'Enter testenv: [py26, py27, py31, py32]',
+        'testenv',
+        validate=_test,
+    )
+    local('tox --recreate -e %(testenv)s' % env)
+
+
+def release():
+    '''release webstring'''
+    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')
+    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 git+ssh://git@github.com:kwarterthieves/webstring.git')
+    local('./setup.py register sdist --format=bztar,gztar,zip upload')
+    local('./setup.py upload_sphinx')
+    local('rm -rf dist')
+
+
+def inplace():
+    '''inplace webstring'''
+    with lcd('./docs/'):
+        local('make clean')
+        local('make html')
+        local('make linkcheck')
+        local('make doctest')
+    with settings(warn_only=True):
+        local('hg push ssh://hg@bitbucket.org/lcrees/webstring')
+        local('hg push git+ssh://git@github.com:kwarterthieves/webstring.git')
+    local('./setup.py sdist --format=bztar,gztar,zip upload')
+    local('./setup.py upload_sphinx')
+    local('rm -rf dist')
+
+
+def release_next():
+    '''release webstring from next branch'''
+    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')
+    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 git+ssh://git@github.com:kwarterthieves/webstring.git')
+    local('./setup.py register sdist --format=bztar,gztar,zip upload')
+    local('rm -rf dist')

File requirements.txt

+stuf>=0.8.14
+lxml>=1.1.1
+[build_sphinx]
+source-dir = docs
+build-dir = docs/_build
+all_files = 1
+
+[upload_sphinx]
+upload-dir = docs/_build/html
 
 setup(
     name='webstring',
-    version='0.5',
+    version='0.6.0',
     description='''
     Template engine that uses Python as the template language
     ''',
     ''',
     author='L. C. Rees',
     author_email='lcrees@gmail.com',
-    url='http://psilib.sourceforge.net/webstring.html',
+    url='https://bitbucket.org/lcrees/webstring/',
     license='BSD',
     packages=['webstring', 'webstring.ext', 'webstring.tests'],
     zip_safe=True,
-    keywords='template text XML HTML XHTML meld TurboGears WSGI',
+    keywords='template text XML HTML XHTML',
     classifiers=[
         'Development Status :: 4 - Beta',
         'Environment :: Web Environment',
         'Topic :: Text Processing :: Markup :: HTML',
         'Topic :: Text Processing :: Markup :: XML'
       ],
-      entry_points='''
-      [python.templating.engines]
-      webstring = webstring.ext.turbogears:TurboWebstring
-      lwebstring = webstring.ext.turbogears:TurboWebstring
-      ''',
-      install_requires=['lxml==1.1.1'],
+      install_requires=[''],
 )
+[tox]
+;no pypy
+envlist = py26,py27,py32
+
+[testenv:py32]
+deps=
+  hg+ssh://hg@bitbucket.org/lcrees/stuf@pu#egg=recipe
+  nose
+  coverage
+commands=
+  nosetests {posargs:--with-coverage  --cover-package=knife}
+
+[testenv:py31]
+deps=
+  hg+ssh://hg@bitbucket.org/lcrees/stuf@pu#egg=recipe
+  unittest2py3k
+  nose
+  coverage
+commands=
+  nosetests {posargs:--with-coverage  --cover-package=knife}
+
+[testenv:py27]
+deps=
+  hg+ssh://hg@bitbucket.org/lcrees/stuf@pu#egg=recipe
+  nose
+  coverage
+commands=
+  nosetests {posargs:--with-coverage --cover-package=knife}
+ 
+[testenv:py26]
+deps=
+  hg+ssh://hg@bitbucket.org/lcrees/stuf@pu#egg=recipe
+  unittest2
+  nose
+  coverage
+commands=
+  nosetests {posargs:--with-coverage  --cover-package=knife}
+  
+[testenv:pypy]
+deps=
+  hg+ssh://hg@bitbucket.org/lcrees/stuf@pu#egg=recipe
+  nose
+  coverage
+commands=
+  nosetests {posargs:--with-coverage  --cover-package=knife}
+  
+[testenv:ipy]
+basepython=ipy
+deps=
+  hg+ssh://hg@bitbucket.org/lcrees/stuf@pu#egg=recipe
+  nose
+  coverage
+commands=
+  nosetests {posargs:--with-coverage --cover-package=knife}

File webstring/__init__.py

 # -*- coding: utf-8 -*-
-
-'''Template engine where Python is the template language.'''
+'''
+Template engine where Python is the template language.
+'''
 
 __author__ = 'L.C. Rees (lcrees-at-gmail.com)'
 __revision__ = (0, 5, 0)
 
-from webstring.xmlt import *
-from webstring.html import *
-from webstring.text import *
-
-
-class Template(object):
-
-    '''Template dispatcher class.'''
-