"""
Close_Last_Open_Tag.py - Inserts a closing tag for the
last un-closed element.  This macro assumes it's bound
to "/", so will always insert a "/".  It's intentionally
naive -- it simply scans backwards in the buffer, ignoring
self-closing elements and closes the last open one.  This
makes it useful for HTML/XML in Javadocs, strings, comments,
etc... where the XML plugin's tag insertion won't work.

Copyright (C) 2004 Ollie Rutherfurd <oliver@rutherfurd.net>

$Id$
"""

def close_last_open_tag(view):
    import re
    TAG_RE = re.compile(r'([A-z][A-z:_0-9-]*)')
    ta = view.getTextArea()
    caret = ta.getCaretPosition()
    text = ta.getText(0,caret)
    pos = caret-1
    stack = 0
    # don't complete if typing a '/' anywhere
    if pos > 0 and text[pos] != '<':
        ta.setSelectedText('/')
        return
    skip = 0
    while pos >= 0:
        c = text[pos]
        n = text[pos+1:pos+2]
        if c == '<':
            #print c, n, stack
            if n == '/':
                stack -= 1
            elif 'A' <= n <= 'z':
                if skip:
                    skip = 0
                else:
                    stack += 1
            if stack > 0:
                m = TAG_RE.match(text[pos+1:])
                if m:
                    ta.setSelectedText('/' + m.group() + '>')
                    return
        # ignore self-closing: <br />, etc...
        elif c == '/' and n == '>':
            skip = 1
        pos -= 1
    ta.setSelectedText('/')

if __name__ == '__main__':
    if buffer.isReadOnly():
        pass
    if not textArea.hasFocus():
        pass
    else:
        close_last_open_tag(view)

