Metadata-Version: 1.0
Name: katagami
Version: 0.1.1
Summary: katagami - a very simple xml template engine.
Home-page: http://pypi.python.org/pypi/katagami
Author: chrono-meter@gmx.net
Author-email: chrono-meter@gmx.net
License: PSF
Description: katagami - a very simple xml template engine.
        =============================================
        
        
        setup...skip to next chapter:
        
            >>> def testfile(file):
            ...     if not hasattr(file, 'read'):
            ...         with open(file) as fp:
            ...             result = render(fp)
            ...     else:
            ...         result = render(file)
            ...     if sys.platform != 'cli': # IronPython doesn't implement unicode.
            ...         result = result.encode()
            ...     return result
            >>> def teststr(t):
            ...     return testfile(StringIO('<html><body>%s</body></html>' % t))
            >>> def echo(name, body):
            ...     with open(os.path.join(tmpdir, name), 'w') as fp:
            ...         fp.write(body)
            >>> def echoxml(name, body):
            ...     echo(name, '<html><body>%s</body></html>' % body)
        
        
        Pythonic evaluation
        -------------------
        
        Dump the value (call `eval` with attribute value):
        
            >>> teststr('''<python value="'hello, world'"/>''')
            '<html><body>hello, world</body></html>'
        
        By the default, xml entities are escaped in `value` attribute of `python` element:
        
            >>> teststr('''<python value="'&lt;p&gt;hello, world&lt;/p&gt;'" escape="false"/>''')
            '<html><body><p>hello, world</p></body></html>'
        
        
        By the default, exceptions are suppressed:
        
            >>> teststr('''<python value="not_found"/>''')
            '<html><body></body></html>'
        
        Use `__mode__` for dump exceptions (and see a helpful traceback):
        
            >>> teststr('''<python __mode__="strict" value="not_found"/>''') # fails in IronPython
            '<html><pre>Traceback (most recent call last):\n  File "&lt;string&gt;", line 1, in Element "body"\n  File "&lt;string&gt;", line 1, in Element "python"\n  File "&lt;string&gt;", line 1, in Element "python" at line 1-1\n    not_found\nNameError: name \'not_found\' is not defined\n</pre></html>'
        
        
        Attribute evaluation (attribute value starts with 'python:'):
        
            >>> teststr('''<p class="python:'python-expr'">hello, world</p>''')
            '<html><body><p class="python-expr">hello, world</p></body></html>'
        
        
        Pythonic statements
        -------------------
        
        All statements are available in all elements.
        
        `if`, `elif`, `else` statements:
        
            >>> teststr('''
            ... <p if="0"/>
            ... <p elif="0"/>
            ... <p else="">output here</p>
            ... ''')
            '<html><body><p>output here</p></body></html>'
        
        
        `for` statement (attribute value is Pythonic for style):
        
            >>> teststr('''<p for_="i, j in enumerate(range(3))"><python value="i, j"/></p>''')
            '<html><body><p>(0, 0)</p><p>(1, 1)</p><p>(2, 2)</p></body></html>'
        
        
        `while` statement:
        
            >>> teststr('''
            ... <python><![CDATA[ i = [1, 2, 3] ]]></python>
            ... <p while="i">
            ...     <python value="i[0]"/>
            ...     <python><![CDATA[ i = i[1:] ]]></python>
            ... </p>
            ... ''')
            '<html><body><p>1</p><p>2</p><p>3</p></body></html>'
        
        
        `except` statement:
        
            >>> teststr('''
            ... <python except="StandardError as e"><![CDATA[ not_found ]]></python>
            ... <python value="e"/>
            ... <python except="StandardError"><![CDATA[ not_found ]]></python>
            ... ''')
            "<html><body>name 'not_found' is not defined</body></html>"
        
        
        `with` statement:
        
            >>> echo('msg.txt', 'hello, world')
            >>> teststr('''
            ... <python with="open(r'%s') as fp">
            ...     <p><python value="fp.read()"/></p>
            ...     <p><python value="fp.closed"/></p>
            ... </python>
            ... <p><python value="fp.closed"/></p>
            ... ''' % os.path.join(tmpdir, 'msg.txt'))
            '<html><body><p>hello, world</p><p>False</p><p>True</p></body></html>'
        
        Multi items are supported (ex. 'with a, b: pass').
        
            >>> echo('msg2.txt', 'hello, world')
            >>> teststr('''
            ... <python with="open(r'%s') as fp, open(r'%s') as fp2">
            ...     <p><python value="fp.read()"/></p>
            ...     <p><python value="fp2.read()"/></p>
            ... </python>
            ... ''' % (os.path.join(tmpdir, 'msg.txt'), os.path.join(tmpdir, 'msg2.txt')))
            '<html><body><p>hello, world</p><p>hello, world</p></body></html>'
        
        
        `def` statement (give context by keyword arguments):
        
            >>> teststr('''
            ... <p def="myfunc">hello, <python value="msg"/></p>
            ... <python value="myfunc(msg='world')" escape="false"/>
            ... ''')
            '<html><body><p>hello,world</p></body></html>'
        
        
        Embedded python script
        ----------------------
        
        `CDATA` is required and use `write` function like DOM's document.write:
        
            >>> teststr('''
            ... <python><![CDATA[
            ...     write('<p>hello, world</p>')
            ... ]]></python>
            ... ''')
            '<html><body><p>hello, world</p></body></html>'
        
        and escape xml entities:
        
            >>> teststr('''
            ... <python><![CDATA[
            ...     write('<p>', 'hello, world', '</p>', escape=True)
            ... ]]></python>
            ... ''')
            '<html><body>&lt;p&gt;hello, world&lt;/p&gt;</body></html>'
        
        
        Include python script file:
        
            >>> echo('sub-script.py', '''write('hello, world')''')
            >>> echoxml('template.html', '''
            ...     <p><python src="sub-script.py"/></p>
            ... ''')
            >>> testfile(os.path.join(tmpdir, 'template.html'))
            '<html><body><p>hello, world</p></body></html>'
        
        and share variables:
        
            >>> echo('sub-script.py', '''
            ... global msg 
            ... msg = 'hello, world'
            ... msg2 = 'hello, world'
            ... global myfunc
            ... def myfunc(name):
            ...     return 'hello, ' + name
            ... ''')
            >>> echoxml('template.html', '''
            ...     <python src="sub-script.py"/>
            ...     <p><python value="msg"/></p>
            ...     <p>
            ...         <python value="msg2" __mode__="strict" except="NameError as e"/>
            ...         <python value="e"/>
            ...     </p>
            ...     <p><python value="myfunc('world')"/></p>
            ... ''')
            >>> testfile(os.path.join(tmpdir, 'template.html'))
            "<html><body><p>hello, world</p><p>name 'msg2' is not defined</p><p>hello, world</p></body></html>"
        
        
        Include another template
        ------------------------
        
        Simply, include all elements:
        
            >>> echoxml('sub-template.html', '<p>hello, world</p>')
            >>> echoxml('template.html', '<python template="sub-template.html"/>')
            >>> testfile(os.path.join(tmpdir, 'template.html'))
            '<html><body><html><body><p>hello, world</p></body></html></body></html>'
        
        Then include a part of elements:
        
            >>> echoxml('sub-template.html', '<p id="myid">hello, world</p>')
            >>> echoxml('template.html',
            ...      '<python template="sub-template.html" fragment="myid"/>')
            >>> testfile(os.path.join(tmpdir, 'template.html'))
            '<html><body><p id="myid">hello, world</p></body></html>'
        
        And share variables:
        
            >>> echoxml('sub-template.html', '''
            ...     <p id="myid">hello, world</p>
            ...     <python><![CDATA[
            ...         global msg
            ...         msg = 'hello, world'
            ...     ]]></python>
            ...     <p def="global myfunc"><python value="text"/></p>
            ... ''')
            >>> echoxml('template.html', '''
            ...     <python template="sub-template.html" fragment="myid"/>
            ...     <p><python value="msg"/></p>
            ...     <python value="myfunc(text='hello, world')" escape="false"/>
            ... ''')
            >>> testfile(os.path.join(tmpdir, 'template.html'))
            '<html><body><p id="myid">hello, world</p><p>hello, world</p><p>hello, world</p></body></html>'
        
        
        Techniques and notices
        ----------------------
        
        This module is wrote under assuming that sys.setdefaultencoding('utf-8').
        
        This module works with null xml namespace, but doesn't remove any namespace:
        
            >>> testfile(StringIO('''<?xml version="1.0"?>
            ... <root xmlns    = "http://default-namespace.org/"
            ...       xmlns:py = "http://www.python.org/ns/">
            ...     <py:elem1 py:if="0"/>
            ...     <elem2 xmlns="" />
            ...     <py:elem3 if="0"/>
            ... </root>'''))
            '<?xml version="1.0"?>\n<root xmlns="http://default-namespace.org/" xmlns:py="http://www.python.org/ns/"><py:elem1 py:if="0"/><elem2 xmlns=""/></root>'
        
        
        The namespace is flat like python module and nested in function:
        
            >>> teststr('''
            ... <python><![CDATA[ a = b = 0 ]]></python>
            ... <python def="myfunc"><![CDATA[
            ...     global a
            ...     write('a = %d\\n' % a)
            ...     write('b = %d\\n' % b)
            ...     a = b = 1
            ... ]]></python>
            ... <python value="myfunc()"/>
            ... <python value="a, b"/>
            ... ''')
            '<html><body>a = 0\nb = 0\n(1, 0)</body></html>'
        
        
        By the default, White spaces and comments are stripped:
        
            >>> teststr('''<p><!-- comment --> hello, world </p>''')
            '<html><body><p>hello, world</p></body></html>'
        
        Use `direct` mode:
        
            >>> teststr('''<p __mode__="direct"><!-- comment --> hello, world </p>''')
            '<html><body><p><!-- comment --> hello, world </p></body></html>'
        
        
        The attribute order is important:
        
            >>> teststr('''
            ... <p if="0" for_="i in range(2)"><python value="i"/></p>
            ... <p for_="i in range(2)" if="i > 0"><python value="i"/></p>
            ... ''')
            '<html><body><p>1</p></body></html>'
        
        
        If you need closing tag such as `textarea`, then write below:
        
            >>> teststr('''<textarea><python/></textarea>''')
            '<html><body><textarea></textarea></body></html>'
        
        
        Entities will not be expanded:
        
            >>> teststr('''&nbsp;&unknown_entity;''')
            '<html><body>&nbsp;&unknown_entity;</body></html>'
        
        
        Special variables are available in some cases:
         * __file__ = str -> path of file (template or script)
         * __noloop__ = bool -> whether loop statements executed
                                (and when not `strict` mode)
         * _ = object -> temporary value when extracting variables
        
        Special utility functions are available, see default_namespace.
        
        Special string codecs:
         * percent, uri - known as encodeURIComponent, decodeURIComponent
         * xml - escape '<', '>', '&'
        
        For more information, see `Element` class implementation.
        
        History
        -------
        * 0.1.1 updated document for PyPI
        * 0.1.0 first release
        
Platform: UNKNOWN
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Python Software Foundation License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 2.7
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content :: CGI Tools/Libraries
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Text Processing :: Markup :: HTML
Classifier: Topic :: Text Processing :: Markup :: XML
