{
    "str_in_list": "def evaluate(self, formatter, kwargs, mi, locals, val, sep, *args):\n    if (len(args) % 2) != 1:\n        raise ValueError(_('str_in_list requires an odd number of arguments'))\n    l = [v.strip() for v in val.split(sep) if v.strip()]\n    i = 0\n    while i < len(args):\n        if i + 1 >= len(args):\n            return args[i]\n        sf = args[i]\n        fv = args[i+1]\n        c = [v.strip() for v in sf.split(sep) if v.strip()]\n        if l:\n            for v in l:\n                for t in c:\n                    if strcmp(t, v) == 0:\n                        return fv\n        i += 2\n", 
    "capitalize": "def evaluate(self, formatter, kwargs, mi, locals, val):\n    return capitalize(val)\n", 
    "list_union": "def evaluate(self, formatter, kwargs, mi, locals, list1, list2, separator):\n    res = [l.strip() for l in list1.split(separator) if l.strip()]\n    l2 = [l.strip() for l in list2.split(separator) if l.strip()]\n    lcl1 = {icu_lower(l) for l in res}\n    for i in l2:\n        if icu_lower(i) not in lcl1 and i not in res:\n            res.append(i)\n    if separator == ',':\n        return ', '.join(res)\n    return separator.join(res)\n", 
    "formats_modtimes": "def evaluate(self, formatter, kwargs, mi, locals, fmt):\n    fmt_data = mi.get('format_metadata', {})\n    try:\n        data = sorted(fmt_data.items(), key=lambda x:x[1]['mtime'], reverse=True)\n        return ','.join(k.upper()+':'+format_date(v['mtime'], fmt)\n                    for k,v in data)\n    except:\n        return ''\n", 
    "and": "def evaluate(self, formatter, kwargs, mi, locals, *args):\n    i = 0\n    while i < len(args):\n        if not args[i]:\n            return ''\n        i += 1\n    return '1'\n", 
    "list_equals": "def evaluate(self, formatter, kwargs, mi, locals, list1, sep1, list2, sep2, yes_val, no_val):\n    s1 = {icu_lower(l.strip()) for l in list1.split(sep1) if l.strip()}\n    s2 = {icu_lower(l.strip()) for l in list2.split(sep2) if l.strip()}\n    if s1 == s2:\n        return yes_val\n    return no_val\n", 
    "count": "def evaluate(self, formatter, kwargs, mi, locals, val, sep):\n    return unicode_type(len([v for v in val.split(sep) if v]))\n", 
    "formats_sizes": "def evaluate(self, formatter, kwargs, mi, locals):\n    fmt_data = mi.get('format_metadata', {})\n    try:\n        return ','.join(k.upper()+':'+unicode_type(v['size']) for k,v in iteritems(fmt_data))\n    except:\n        return ''\n", 
    "strcat": "def evaluate(self, formatter, kwargs, mi, locals, *args):\n    i = 0\n    res = ''\n    for i in range(0, len(args)):\n        res += args[i]\n    return res\n", 
    "current_library_path": "def evaluate(self, formatter, kwargs, mi, locals):\n    from calibre.library import current_library_path\n    return current_library_path()\n", 
    "raw_field": "def evaluate(self, formatter, kwargs, mi, locals, name):\n    res = getattr(mi, name, None)\n    if isinstance(res, list):\n        fm = mi.metadata_for_field(name)\n        if fm is None:\n            return ', '.join(res)\n        return fm['is_multiple']['list_to_ui'].join(res)\n    return unicode_type(res)\n", 
    "swap_around_comma": "def evaluate(self, formatter, kwargs, mi, locals, val):\n    return re.sub(r'^(.*?),\\s*(.*$)', r'\\2 \\1', val, flags=re.I).strip()\n", 
    "formats_paths": "def evaluate(self, formatter, kwargs, mi, locals):\n    fmt_data = mi.get('format_metadata', {})\n    try:\n        return ','.join(k.upper()+':'+unicode_type(v['path']) for k,v in iteritems(fmt_data))\n    except:\n        return ''\n", 
    "list_re": "def evaluate(self, formatter, kwargs, mi, locals, src_list, separator, include_re, opt_replace):\n    l = [l.strip() for l in src_list.split(separator) if l.strip()]\n    res = []\n    for item in l:\n        if re.search(include_re, item, flags=re.I) is not None:\n            if opt_replace:\n                item = re.sub(include_re, opt_replace, item)\n            for i in [t.strip() for t in item.split(separator) if t.strip()]:\n                if i not in res:\n                    res.append(i)\n    if separator == ',':\n        return ', '.join(res)\n    return separator.join(res)\n", 
    "list_sort": "def evaluate(self, formatter, kwargs, mi, locals, list1, direction, separator):\n    res = [l.strip() for l in list1.split(separator) if l.strip()]\n    if separator == ',':\n        return ', '.join(sorted(res, key=sort_key, reverse=direction != \"0\"))\n    return separator.join(sorted(res, key=sort_key, reverse=direction != \"0\"))\n", 
    "field": "def evaluate(self, formatter, kwargs, mi, locals, name):\n    return formatter.get_value(name, [], kwargs)\n", 
    "not": "def evaluate(self, formatter, kwargs, mi, locals, val):\n    return '' if val else '1'\n", 
    "subitems": "def evaluate(self, formatter, kwargs, mi, locals, val, start_index, end_index):\n    if not val:\n        return ''\n    si = int(start_index)\n    ei = int(end_index)\n    has_periods = '.' in val\n    items = [v.strip() for v in val.split(',')]\n    rv = set()\n    for item in items:\n        if has_periods and '.' in item:\n            components = self.period_pattern.split(item)\n        else:\n            components = [item]\n        try:\n            if ei == 0:\n                rv.add('.'.join(components[si:]))\n            else:\n                rv.add('.'.join(components[si:ei]))\n        except:\n            pass\n    return ', '.join(sorted(rv, key=sort_key))\n", 
    "list_intersection": "def evaluate(self, formatter, kwargs, mi, locals, list1, list2, separator):\n    l1 = [l.strip() for l in list1.split(separator) if l.strip()]\n    l2 = {icu_lower(l.strip()) for l in list2.split(separator) if l.strip()}\n    res = []\n    for i in l1:\n        if icu_lower(i) in l2 and i not in res:\n            res.append(i)\n    if separator == ',':\n        return ', '.join(res)\n    return separator.join(res)\n", 
    "lookup": "def evaluate(self, formatter, kwargs, mi, locals, val, *args):\n    if len(args) == 2:  # here for backwards compatibility\n        if val:\n            return formatter.vformat('{'+args[0].strip()+'}', [], kwargs)\n        else:\n            return formatter.vformat('{'+args[1].strip()+'}', [], kwargs)\n    if (len(args) % 2) != 1:\n        raise ValueError(_('lookup requires either 2 or an odd number of arguments'))\n    i = 0\n    while i < len(args):\n        if i + 1 >= len(args):\n            return formatter.vformat('{' + args[i].strip() + '}', [], kwargs)\n        if re.search(args[i], val, flags=re.I):\n            return formatter.vformat('{'+args[i+1].strip() + '}', [], kwargs)\n        i += 2\n", 
    "lowercase": "def evaluate(self, formatter, kwargs, mi, locals, val):\n    return val.lower()\n", 
    "raw_list": "def evaluate(self, formatter, kwargs, mi, locals, name, separator):\n    res = getattr(mi, name, None)\n    if not isinstance(res, list):\n        return \"%s is not a list\" % name\n    return separator.join(res)\n", 
    "human_readable": "def evaluate(self, formatter, kwargs, mi, locals, val):\n    try:\n        return human_readable(round(float(val)))\n    except:\n        return ''\n", 
    "divide": "def evaluate(self, formatter, kwargs, mi, locals, x, y):\n    x = float(x if x and x != 'None' else 0)\n    y = float(y if y and y != 'None' else 0)\n    return unicode_type(x / y)\n", 
    "days_between": "def evaluate(self, formatter, kwargs, mi, locals, date1, date2):\n    try:\n        d1 = parse_date(date1)\n        if d1 == UNDEFINED_DATE:\n            return ''\n        d2 = parse_date(date2)\n        if d2 == UNDEFINED_DATE:\n            return ''\n    except:\n        return ''\n    i = d1 - d2\n    return '%.1f'%(i.days + (i.seconds/(24.0*60.0*60.0)))\n", 
    "format_date": "def evaluate(self, formatter, kwargs, mi, locals, val, format_string):\n    if not val or val == 'None':\n        return ''\n    try:\n        dt = parse_date(val)\n        s = format_date(dt, format_string)\n    except:\n        s = 'BAD DATE'\n    return s\n", 
    "add": "def evaluate(self, formatter, kwargs, mi, locals, x, y):\n    x = float(x if x and x != 'None' else 0)\n    y = float(y if y and y != 'None' else 0)\n    return unicode_type(x + y)\n", 
    "re": "def evaluate(self, formatter, kwargs, mi, locals, val, pattern, replacement):\n    return re.sub(pattern, replacement, val, flags=re.I)\n", 
    "author_links": "def evaluate(self, formatter, kwargs, mi, locals, val_sep, pair_sep):\n    if hasattr(mi, '_proxy_metadata'):\n        link_data = mi._proxy_metadata.author_link_map\n        if not link_data:\n            return ''\n        names = sorted(link_data.keys(), key=sort_key)\n        return pair_sep.join(n + val_sep + link_data[n] for n in names)\n    return _('This function can be used only in the GUI')\n", 
    "list_item": "def evaluate(self, formatter, kwargs, mi, locals, val, index, sep):\n    if not val:\n        return ''\n    index = int(index)\n    val = val.split(sep)\n    try:\n        return val[index].strip()\n    except:\n        return ''\n", 
    "list_difference": "def evaluate(self, formatter, kwargs, mi, locals, list1, list2, separator):\n    l1 = [l.strip() for l in list1.split(separator) if l.strip()]\n    l2 = {icu_lower(l.strip()) for l in list2.split(separator) if l.strip()}\n    res = []\n    for i in l1:\n        if icu_lower(i) not in l2 and i not in res:\n            res.append(i)\n    if separator == ',':\n        return ', '.join(res)\n    return separator.join(res)\n", 
    "language_strings": "def evaluate(self, formatter, kwargs, mi, locals, lang_codes, localize):\n    retval = []\n    for c in [c.strip() for c in lang_codes.split(',') if c.strip()]:\n        try:\n            n = calibre_langcode_to_name(c, localize != '0')\n            if n:\n                retval.append(n)\n        except:\n            pass\n    return ', '.join(retval)\n", 
    "first_non_empty": "def evaluate(self, formatter, kwargs, mi, locals, *args):\n    i = 0\n    while i < len(args):\n        if args[i]:\n            return args[i]\n        i += 1\n    return ''\n", 
    "uppercase": "def evaluate(self, formatter, kwargs, mi, locals, val):\n    return val.upper()\n", 
    "approximate_formats": "def evaluate(self, formatter, kwargs, mi, locals):\n    if hasattr(mi, '_proxy_metadata'):\n        fmt_data = mi._proxy_metadata.db_approx_formats\n        if not fmt_data:\n            return ''\n        data = sorted(fmt_data)\n        return ','.join(v.upper() for v in data)\n    return _('This function can be used only in the GUI')\n", 
    "ondevice": "def evaluate(self, formatter, kwargs, mi, locals):\n    if hasattr(mi, '_proxy_metadata'):\n        if mi._proxy_metadata.ondevice_col:\n            return _('Yes')\n        return ''\n    return _('This function can be used only in the GUI')\n", 
    "language_codes": "def evaluate(self, formatter, kwargs, mi, locals, lang_strings):\n    retval = []\n    for c in [c.strip() for c in lang_strings.split(',') if c.strip()]:\n        try:\n            cv = canonicalize_lang(c)\n            if cv:\n                retval.append(canonicalize_lang(cv))\n        except:\n            pass\n    return ', '.join(retval)\n", 
    "eval": "def evaluate(self, formatter, kwargs, mi, locals, template):\n    from formatter import EvalFormatter\n    template = template.replace('[[', '{').replace(']]', '}')\n    return EvalFormatter().safe_format(template, locals, 'EVAL', None)\n", 
    "or": "def evaluate(self, formatter, kwargs, mi, locals, *args):\n    i = 0\n    while i < len(args):\n        if args[i]:\n            return '1'\n        i += 1\n    return ''\n", 
    "print": "def evaluate(self, formatter, kwargs, mi, locals, *args):\n    print(args)\n    return ''\n", 
    "strcmp": "def evaluate(self, formatter, kwargs, mi, locals, x, y, lt, eq, gt):\n    v = strcmp(x, y)\n    if v < 0:\n        return lt\n    if v == 0:\n        return eq\n    return gt\n", 
    "select": "def evaluate(self, formatter, kwargs, mi, locals, val, key):\n    if not val:\n        return ''\n    vals = [v.strip() for v in val.split(',')]\n    for v in vals:\n        if v.startswith(key+':'):\n            return v[len(key)+1:]\n    return ''\n", 
    "sublist": "def evaluate(self, formatter, kwargs, mi, locals, val, start_index, end_index, sep):\n    if not val:\n        return ''\n    si = int(start_index)\n    ei = int(end_index)\n    # allow empty list items so counts are what the user expects\n    val = [v.strip() for v in val.split(sep)]\n    if sep == ',':\n        sep = ', '\n    try:\n        if ei == 0:\n            return sep.join(val[si:])\n        else:\n            return sep.join(val[si:ei])\n    except:\n        return ''\n", 
    "contains": "def evaluate(self, formatter, kwargs, mi, locals,\n             val, test, value_if_present, value_if_not):\n    if re.search(test, val, flags=re.I):\n        return value_if_present\n    else:\n        return value_if_not\n", 
    "series_sort": "def evaluate(self, formatter, kwargs, mi, locals):\n    if mi.series:\n        return title_sort(mi.series)\n    return ''\n", 
    "list_re_group": "def evaluate(self, formatter, kwargs, mi, locals, src_list, separator, include_re,\n             search_re, *args):\n    from formatter import EvalFormatter\n    l = [l.strip() for l in src_list.split(separator) if l.strip()]\n    res = []\n    for item in l:\n        def repl(mo):\n            newval = ''\n            if mo and mo.lastindex:\n                for dex in range(0, mo.lastindex):\n                    gv = mo.group(dex+1)\n                    if gv is None:\n                        continue\n                    if len(args) > dex:\n                        template = args[dex].replace('[[', '{').replace(']]', '}')\n                        newval += EvalFormatter().safe_format(template, {'$': gv},\n                                          'EVAL', None, strip_results=False)\n                    else:\n                        newval += gv\n            return newval\n        if re.search(include_re, item, flags=re.I) is not None:\n            item = re.sub(search_re, repl, item, flags=re.I)\n            for i in [t.strip() for t in item.split(separator) if t.strip()]:\n                if i not in res:\n                    res.append(i)\n    if separator == ',':\n        return ', '.join(res)\n    return separator.join(res)\n", 
    "today": "def evaluate(self, formatter, kwargs, mi, locals):\n    return format_date(now(), 'iso')\n", 
    "has_cover": "def evaluate(self, formatter, kwargs, mi, locals):\n    if mi.has_cover:\n        return _('Yes')\n    return ''\n", 
    "substr": "def evaluate(self, formatter, kwargs, mi, locals, str_, start_, end_):\n    return str_[int(start_): len(str_) if int(end_) == 0 else int(end_)]\n", 
    "cmp": "def evaluate(self, formatter, kwargs, mi, locals, x, y, lt, eq, gt):\n    x = float(x if x and x != 'None' else 0)\n    y = float(y if y and y != 'None' else 0)\n    if x < y:\n        return lt\n    if x == y:\n        return eq\n    return gt\n", 
    "assign": "def evaluate(self, formatter, kwargs, mi, locals, target, value):\n    locals[target] = value\n    return value\n", 
    "transliterate": "def evaluate(self, formatter, kwargs, mi, locals, source):\n    from calibre.utils.filenames import ascii_text\n    return ascii_text(source)\n", 
    "test": "def evaluate(self, formatter, kwargs, mi, locals, val, value_if_set, value_not_set):\n    if val:\n        return value_if_set\n    else:\n        return value_not_set\n", 
    "author_sorts": "def evaluate(self, formatter, kwargs, mi, locals, val_sep):\n    sort_data = mi.author_sort_map\n    if not sort_data:\n        return ''\n    names = [sort_data.get(n) for n in mi.authors if n.strip()]\n    return val_sep.join(n for n in names)\n", 
    "format_number": "def evaluate(self, formatter, kwargs, mi, locals, val, template):\n    if val == '' or val == 'None':\n        return ''\n    if '{' not in template:\n        template = '{0:' + template + '}'\n    try:\n        v1 = float(val)\n    except:\n        return ''\n    try:  # Try formatting the value as a float\n        return template.format(v1)\n    except:\n        pass\n    try:  # Try formatting the value as an int\n        v2 = trunc(v1)\n        if v2 == v1:\n            return template.format(v2)\n    except:\n        pass\n    return ''\n", 
    "in_list": "def evaluate(self, formatter, kwargs, mi, locals, val, sep, *args):\n    if (len(args) % 2) != 1:\n        raise ValueError(_('in_list requires an odd number of arguments'))\n    l = [v.strip() for v in val.split(sep) if v.strip()]\n    i = 0\n    while i < len(args):\n        if i + 1 >= len(args):\n            return args[i]\n        sf = args[i]\n        fv = args[i+1]\n        if l:\n            for v in l:\n                if re.search(sf, v, flags=re.I):\n                    return fv\n        i += 2\n", 
    "user_categories": "def evaluate(self, formatter, kwargs, mi, locals_):\n    if hasattr(mi, '_proxy_metadata'):\n        cats = set(k for k, v in iteritems(mi._proxy_metadata.user_categories) if v)\n        cats = sorted(cats, key=sort_key)\n        return ', '.join(cats)\n    return _('This function can be used only in the GUI')\n", 
    "multiply": "def evaluate(self, formatter, kwargs, mi, locals, x, y):\n    x = float(x if x and x != 'None' else 0)\n    y = float(y if y and y != 'None' else 0)\n    return unicode_type(x * y)\n", 
    "shorten": "def evaluate(self, formatter, kwargs, mi, locals,\n             val, leading, center_string, trailing):\n    l = max(0, int(leading))\n    t = max(0, int(trailing))\n    if len(val) > l + len(center_string) + t:\n        return val[0:l] + center_string + ('' if t == 0 else val[-t:])\n    else:\n        return val\n", 
    "strcat_max": "def evaluate(self, formatter, kwargs, mi, locals, *args):\n    if len(args) < 2:\n        raise ValueError(_('strcat_max requires 2 or more arguments'))\n    if (len(args) % 2) != 0:\n        raise ValueError(_('strcat_max requires an even number of arguments'))\n    try:\n        max = int(args[0])\n    except:\n        raise ValueError(_('first argument to strcat_max must be an integer'))\n    i = 2\n    result = args[1]\n    try:\n        while i < len(args):\n            if (len(result) + len(args[i]) + len(args[i+1])) > max:\n                break\n            result = result + args[i] + args[i+1]\n            i += 2\n    except:\n        pass\n    return result.strip()\n", 
    "re_group": "def evaluate(self, formatter, kwargs, mi, locals, val, pattern, *args):\n    from formatter import EvalFormatter\n    def repl(mo):\n        res = ''\n        if mo and mo.lastindex:\n            for dex in range(0, mo.lastindex):\n                gv = mo.group(dex+1)\n                if gv is None:\n                    continue\n                if len(args) > dex:\n                    template = args[dex].replace('[[', '{').replace(']]', '}')\n                    res += EvalFormatter().safe_format(template, {'$': gv},\n                                       'EVAL', None, strip_results=False)\n                else:\n                    res += gv\n        return res\n    return re.sub(pattern, repl, val, flags=re.I)\n", 
    "subtract": "def evaluate(self, formatter, kwargs, mi, locals, x, y):\n    x = float(x if x and x != 'None' else 0)\n    y = float(y if y and y != 'None' else 0)\n    return unicode_type(x - y)\n", 
    "virtual_libraries": "def evaluate(self, formatter, kwargs, mi, locals_):\n    if hasattr(mi, '_proxy_metadata'):\n        return mi._proxy_metadata.virtual_libraries\n    return _('This function can be used only in the GUI')\n", 
    "finish_formatting": "def evaluate(self, formatter, kwargs, mi, locals_, val, fmt, prefix, suffix):\n    if not val:\n        return val\n    return prefix + formatter._do_format(val, fmt) + suffix\n", 
    "current_library_name": "def evaluate(self, formatter, kwargs, mi, locals):\n    from calibre.library import current_library_name\n    return current_library_name()\n", 
    "booksize": "def evaluate(self, formatter, kwargs, mi, locals):\n    if hasattr(mi, '_proxy_metadata'):\n        try:\n            v = mi._proxy_metadata.book_size\n            if v is not None:\n                return unicode_type(mi._proxy_metadata.book_size)\n            return ''\n        except:\n            pass\n        return ''\n    return _('This function can be used only in the GUI')\n", 
    "first_matching_cmp": "def evaluate(self, formatter, kwargs, mi, locals, *args):\n    if (len(args) % 2) != 0:\n        raise ValueError(_('first_matching_cmp requires an even number of arguments'))\n    val = float(args[0] if args[0] and args[0] != 'None' else 0)\n    for i in range(1, len(args) - 1, 2):\n        c = float(args[i] if args[i] and args[i] != 'None' else 0)\n        if val < c:\n            return args[i+1]\n    return args[len(args)-1]\n", 
    "switch": "def evaluate(self, formatter, kwargs, mi, locals, val, *args):\n    if (len(args) % 2) != 1:\n        raise ValueError(_('switch requires an odd number of arguments'))\n    i = 0\n    while i < len(args):\n        if i + 1 >= len(args):\n            return args[i]\n        if re.search(args[i], val, flags=re.I):\n            return args[i+1]\n        i += 2\n", 
    "ifempty": "def evaluate(self, formatter, kwargs, mi, locals, val, value_if_empty):\n    if val:\n        return val\n    else:\n        return value_if_empty\n", 
    "identifier_in_list": "def evaluate(self, formatter, kwargs, mi, locals, val, ident, fv, nfv):\n    l = [v.strip() for v in val.split(',') if v.strip()]\n    (id, _, regexp) = ident.partition(':')\n    if not id:\n        return nfv\n    id += ':'\n    if l:\n        for v in l:\n            if v.startswith(id):\n                if not regexp or re.search(regexp, v[len(id):], flags=re.I):\n                    return fv\n    return nfv\n", 
    "strlen": "def evaluate(self, formatter, kwargs, mi, locals, a):\n    try:\n        return len(a)\n    except:\n        return -1\n", 
    "titlecase": "def evaluate(self, formatter, kwargs, mi, locals, val):\n    return titlecase(val)\n", 
    "template": "def evaluate(self, formatter, kwargs, mi, locals, template):\n    template = template.replace('[[', '{').replace(']]', '}')\n    return formatter.__class__().safe_format(template, kwargs, 'TEMPLATE', mi)\n"
}