'Returns a data structure that represents the indices at which the
template changes from HTML context to JavaScript and back.
Return:
A list of dicts where each dict contains:
- index: the index of the context.
- type: the context type (e.g. \'html\' or \'javascript\').'

def _get_contexts(self, mako_template):

    contexts_re = re.compile('\n                                                                <script.*?>    |        #    script    tag    start\n                                                                </script>    |        #    script    tag    end\n                                                                <%static:require_module(_async)?.*?>    |        #    require    js    script    tag    start    (optionally    the    _async    version)\n                                                                </%static:require_module(_async)?>    |    #    require    js    script    tag    end    (optionally    the    _async    version)\n                                                                <%static:webpack.*?>    |        #    webpack    script    tag    start\n                                                                </%static:webpack>    |    #    webpack    script    tag    end\n                                                                <%block[    ]*name=[\'"]requirejs[\'"]\\w*>    |        #    require    js    tag    start\n                                                                </%block>        #    require    js    tag    end\n                                                ', (re.VERBOSE | re.IGNORECASE))
    media_type_re = re.compile('type=[\'"].*?[\'"]', re.IGNORECASE)
    contexts = [{'index': 0, 'type': 'html'}]
    javascript_types = ['text/javascript', 'text/ecmascript', 'application/ecmascript', 'application/javascript', 'text/x-mathjax-config', 'json/xblock-args', 'application/json']
    html_types = ['text/template']
    for context in contexts_re.finditer(mako_template):
        match_string = context.group().lower()
        if match_string.startswith('<script'):
            match_type = media_type_re.search(match_string)
            context_type = 'javascript'
            if (match_type is not None):
                match_type = match_type.group()[6:(-1)].lower()
                if (match_type in html_types):
                    context_type = 'html'
                elif (match_type not in javascript_types):
                    context_type = 'unknown'
            contexts.append({'index': context.end(), 'type': context_type})
        elif match_string.startswith('</'):
            contexts.append({'index': context.start(), 'type': 'html'})
        else:
            contexts.append({'index': context.end(), 'type': 'javascript'})
    return contexts
