def _fix_keys(key_mapping, inibin, string_table=None):
    """
    Return a human-readable dictionary from the inibin.

    Arguments:
    key_mapping -- Dictionary used for conversion. Supports nesting. Every other
        value should be a numeric inibin key, or a tuple of the key and a
        function to apply to the result.
    inibin -- The dictionary returned from reading an inibin.
    string_table -- Used to translate strings. Any string with a key in
        string_table will be replaced. Typically loaded from a fontconfig_*.txt.
    """
    if string_table is None:
        string_table = {}

    def walk(node, out_node):
        # Walk the nodes of the key mapping
        for key, value in node.items():
            if isinstance(value, dict):
                if key not in out_node:
                    out_node[key] = {}
                walk(value, out_node[key])
            else:
                # Can either be just the index, or the index plus a function to apply
                func = None
                if isinstance(value, tuple):
                    func = value[-1]
                    index = value[0]
                else:
                    index = value

                if index is None or index not in inibin:
                    out_node[key] = None
                    continue

                val = inibin[index]

                # Try numeric conversion
                # Inibins often store numbers in strings
                if isinstance(val, bytes):
                    try:
                        val = int(val)
                    except ValueError:
                        try:
                            val = float(val)
                        except ValueError:
                            val = val.decode('utf8')

                # Check if value is a reference to a fontconfig key
                if val in string_table:
                    val = string_table[val]

                # Apply the function
                if callable(func):
                    val = func(val)

                out_node[key] = val

    out = {}
    walk(key_mapping, out)

    return out
Return a human-readable dictionary from the inibin.

    Arguments:
    key_mapping -- Dictionary used for conversion. Supports nesting. Every other
        value should be a numeric inibin key, or a tuple of the key and a
        function to apply to the result.
    inibin -- The dictionary returned from reading an inibin.
    string_table -- Used to translate strings. Any string with a key in
        string_table will be replaced. Typically loaded from a fontconfig_*.txt.