def read_pprog(filename):
    """
    Read a Bruker pulse program (pulseprogram) file.

    Resultsing dictionary contains the following keys:

    ========    ===========================================================
    key         description
    ========    ===========================================================
    var         dictionary of variables assigned in pulseprogram
    incr        list of lists containing increment times
    loop        list of loop multipliers
    phase       list of lists containing phase elements
    ph_extra    list of lists containing comments at the end of phase lines
    ========    ===========================================================

    The incr,phase and ph_extra lists match up with loop list.  For example
    incr[0],phase[0] and ph_extra[0] are all increment and phase commands
    with comments which occur during loop 0 which has loop[0] steps.

    Parameters
    ----------
    filename : str
        Filename of pulseprogram file to read from,

    Returns
    -------
    dic : dict
        A dictionary with keys described above.

    See Also
    --------
    write_pprog : Write a Bruker pulse program to file.

    """
    f = open(filename, 'r')
    var = dict()
    loop = []
    incr = [[]]
    phase = [[]]
    ph_extra = [[]]
    for line in f:
        if ';' in line:
            comment = line[line.index(';'):]
            text = line[:line.index(';')].strip()
        else:
            comment = ''
            text = line.strip()
        if len(text.split()) != 0:
            s = text.split()[0]
            if s.isdigit() or s[-1] == ',':
                text = text[len(s):].strip()
        if text == '' or text[0] == '#':
            continue
        if '"' in text:
            if '=' in line:
                text = text.strip('"')
                t = text.split('=')
                if len(t) >= 2:
                    key, value = t[0], t[1]
                    var[key] = value
                else:
                    pass
                continue
            else:
                continue
        if text[0:2] == 'lo':
            loop.append(text.split()[4])
            incr.append([])
            phase.append([])
            ph_extra.append([])
            continue
        tokens = text.split()
        if len(tokens) >= 2:
            token2 = tokens[1]
            if token2.startswith('id') or token2.startswith('dd'):
                incr[len(loop)].append(int(token2[2:]))
                continue
            if token2.startswith('ipu') or token2.startswith('dpu'):
                incr[len(loop)].append(int(token2[3:]))
                continue
            if token2.startswith('ip') or token2.startswith('dp'):
                phase[len(loop)].append(int(token2[2:]))
                last = text.find(' ', text.index('ip'))
                if last == -1:
                    ph_extra[len(loop)].append('')
                else:
                    ph_extra[len(loop)].append(text[last:].strip())
                continue
    f.close()
    incr.pop()
    phase.pop()
    ph_extra.pop()
    for i, t in enumerate(loop):
        if t.isdigit():
            loop[i] = int(t)
        elif t in var and var[t].isdigit():
            loop[i] = int(var[t])
    dic = {'var': var, 'incr': incr, 'loop': loop, 'phase': phase,
        'ph_extra': ph_extra}
    return dic
