#!/usr/bin/python

def escape_core(level, text):
    '''
    Used by `escape`
    
    Levels of escaping
    ------------------
    
        `level` == 0: No treatment.
        `level` == 1: '<', '>' and '&'
        `level` == 2: '<', '>', '&', '"' and "'"
    '''
    text = '{}'.format(text)
    if level == 0:
        return text
    elif level >= 1:
        escaped = text.replace(
            '&', '&amp;').replace(
            '<', '&lt;').replace(
            '>', '&gt;'
        )
        if level == 1:
            return escaped
        elif level >= 2:
            return escaped.replace('"', '&quot;').replace("'", '&apos;')
        else:
            assert False, "Level too high."


def escape(s, *args, **kwargs):
    '''
    (CGI) escaping replacement for `str.format`.
    
    escape('<a href={}>{}</a>',
        2, 'http://example.com/',
        1, 'example.com',
    )
    
    Arguments: s [level text] ... [key=(level, text)] ...
    
    Levels of escaping
    ------------------
    
        `level` == 0: No treatment.
        `level` == 1: '<', '>' and '&'
        `level` == 2: '<', '>', '&', '"' and "'"
    '''
    assert len(args)%2 == 0
    
    args = list(args) # Needed for `pop`ping.
    
    safe_args = []
    while args:
        level = args.pop(0)
        text = args.pop(0)
        safe_args.append(escape_core(level, text))
    
    safe_kwargs = {}
    for key in kwargs:
        safe_kwargs[key] = escape_core(kwargs[key][0], kwargs[key][1])
    
    return s.format(*safe_args, **safe_kwargs)