<commit_before>#!/usr/bin/env python
""" nontemplate is not a templating language """

class Element:
    """ An element within a nontemplate document """
    document = None
    tag_name = None
    element = None
    
    def __init__(self, document, tag_name):
        self.document = document
        self.tag_name = tag_name 
        
    def __call__(self, *args, **kwargs):
        self.element = lxml.etree.Element(self.tag_name, **kwargs)
        return self
    
    def __enter__(self):
        self.document._enter(self)
    
    def __exit__(self, type, value, tb):
        self.document._exit(self)

    def open_tag(self):
        return "<%s>" % self.tag_name
    
    def close_tag(self):
        return "</%s>\n" % self.tag_name
    
class Document:
    """ A nontemplate document ... emits XML """
    
    def __init__(self, output):
        self._output = output or ""
    
    def _emit(self, text):        
        if type(self._output) is str:
            self.output += text
        elif type(self._output) is list:
            self._output.append(text)
        else:
            self._output(text)
    
    def _enter(self, element):
        self._emit(element.open_tag())
    
    def _exit(self, element):
        self._emit(element.close_tag())
    
    def __getattr__(self, name):
        return Element(self, name)

    def __repr__(self):
        return "nontemplate Document Instance"
    
    def __str__(self):
        return self._output
    
<commit_msg>Updated version<commit_after>#!/usr/bin/env python

class DocumentTag:
    
    name = None
    attrs = {}
    elems = []
    
    def __init__(self, document, name):
        self.name = name
        self.document = document
        self.tagged = False
        
    def __call__(self, *args, **kwargs):
        self.attr = kwargs
        
        for a in args:
            if type(a) is dict:
                self.attrs.update(a)
            elif type(a) in (unicode, str):
                self.elems.append(a)
            elif type(a) in (list, tuple):
                self.elems += str(a)
            else:
                self.elems += a.elems
            
        return self
    
    def __enter__(self):
        if not self.tagged:
            self.document._tag(self.name)
            self.tagged = True
        self.document._rewind()
            
    def __exit__(self, type, value, tb):
        self.document._forward()

    def __str__(self):
        return ( ("<%s" % self.name ) +
            ''.join([ '%s="%s"' % x for x in self.attrs.iteritems() ]) +
            ">" +
            ''.join(self.elems) +
            ("</%s>" % self.name)
        )
    
class Document:

    _head = []
    _tail = []
    
    def _tag(self, tagname, *args, **kwargs):
        opentag = "<%s" % tagname
        for x,y in kwargs.iteritems():
            opentag += ' %s="%s"' % ((x[1:] if x[0] == '_' else x), y)
        opentag += ">"
        self._head.append(opentag)
        
        for x in args:
            if type(x) in (list, tuple):
                self._head += list(x)
            elif type(x) in (str, unicode):
                self._head.append(x)
            else:
                x()
                
        self._head.append("</%s>\n" % tagname)
    
    def _text(self, text):
        self._head += [ text ]
        
    def _rewind(self):
        self._tail.append(self._head.pop())
        
    def _forward(self):
        self._head.append(self._tail.pop())
            
    def __getattr__(self, name):
        return DocumentTag(self, name)

    def __repr__(self):
        return "Document Instance"

    
D = Document();

with D.html:
    D.head(D.title("foo"))
    with D.body:
        for y in range(0,3):
            with D.p(_class="bar"):
                for x in range(0,3):
                    D.img(src="baz%d-%d.jpg" % (x,y))
                    D.caption("Testing %d-%d" % (y,x))
            
print ''.join(D._head)
{'fraction_non_alphanumeric': 0.13245369195635626, 'fraction_numerical': 0.0015224562293834052, 'mean_word_length': 1.581532416502947, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 1}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3253199', 'n_tokens_mistral': 1249, 'n_tokens_neox': 1228, 'n_words': 286}