def _getSmartIndenter(indenterName, qpart, indenter):
    """Get indenter by name.
    Available indenters are none, normal, cstyle, haskell, lilypond, lisp, python, ruby, xml
    Indenter name is not case sensitive
    Raise KeyError if not found
    indentText is indentation, which shall be used. i.e. '\t' for tabs, '    ' for 4 space symbols
    """
    indenterName = indenterName.lower()

    if indenterName in ('haskell', 'lilypond'):  # not supported yet
        logger.warning('Smart indentation for %s not supported yet. But you could be a hero who implemented it' % indenterName)
        from qutepart.indenter.base import IndentAlgNormal as indenterClass
    elif 'none' == indenterName:
        from qutepart.indenter.base import IndentAlgBase as indenterClass
    elif 'normal' == indenterName:
        from qutepart.indenter.base import IndentAlgNormal as indenterClass
    elif 'cstyle' == indenterName:
        from qutepart.indenter.cstyle import IndentAlgCStyle as indenterClass
    elif 'python' == indenterName:
        from qutepart.indenter.python import IndentAlgPython as indenterClass
    elif 'ruby' == indenterName:
        from qutepart.indenter.ruby import IndentAlgRuby as indenterClass
    elif 'xml' == indenterName:
        from qutepart.indenter.xmlindent import IndentAlgXml as indenterClass
    elif 'haskell' == indenterName:
        from qutepart.indenter.haskell import IndenterHaskell as indenterClass
    elif 'lilypond' == indenterName:
        from qutepart.indenter.lilypond import IndenterLilypond as indenterClass
    elif 'lisp' == indenterName:
        from qutepart.indenter.lisp import IndentAlgLisp as indenterClass
    elif 'scheme' == indenterName:
        from qutepart.indenter.scheme import IndentAlgScheme as indenterClass
    else:
        raise KeyError("Indenter %s not found" % indenterName)

    return indenterClass(qpart, indenter)
def readpatternfile(filepath, warn, sourceinfo=False):
    """parse a pattern file, returning a list of
    patterns. These patterns should be given to compile()
    to be validated and converted into a match function.

    trailing white space is dropped.
    the escape character is backslash.
    comments start with #.
    empty lines are skipped.

    lines can be of the following formats:

    syntax: regexp # defaults following lines to non-rooted regexps
    syntax: glob   # defaults following lines to non-rooted globs
    re:pattern     # non-rooted regular expression
    glob:pattern   # non-rooted glob
    pattern        # pattern of the current default type

    if sourceinfo is set, returns a list of tuples:
    (pattern, lineno, originalline). This is useful to debug ignore patterns.
    """

    syntaxes = {
        "re": "relre:",
        "regexp": "relre:",
        "glob": "relglob:",
        "include": "include",
        "subinclude": "subinclude",
    }
    syntax = "relre:"
    patterns = []

    fp = open(filepath, "rb")
    for lineno, line in enumerate(util.iterfile(fp), start=1):
        if "#" in line:
            global _commentre
            if not _commentre:
                _commentre = util.re.compile(br"((?:^|[^\\])(?:\\\\)*)#.*")
            # remove comments prefixed by an even number of escapes
            m = _commentre.search(line)
            if m:
                line = line[: m.end(1)]
            # fixup properly escaped comments that survived the above
            line = line.replace("\\#", "#")
        line = line.rstrip()
        if not line:
            continue

        if line.startswith("syntax:"):
            s = line[7:].strip()
            try:
                syntax = syntaxes[s]
            except KeyError:
                if warn:
                    warn(_("%s: ignoring invalid syntax '%s'\n") % (filepath, s))
            continue

        linesyntax = syntax
        for s, rels in pycompat.iteritems(syntaxes):
            if line.startswith(rels):
                linesyntax = rels
                line = line[len(rels) :]
                break
            elif line.startswith(s + ":"):
                linesyntax = rels
                line = line[len(s) + 1 :]
                break
        if sourceinfo:
            patterns.append((linesyntax + line, lineno, line))
        else:
            patterns.append(linesyntax + line)
    fp.close()
    return patterns