def generate_operators(declarations_only=False): all_nicknames = [] def add_nickname(gtype, a, b): nickname = nickname_find(gtype) try: # can fail for abstract types op = Operation.new_from_name(nickname) # we are only interested in non-deprecated operations if (op.get_flags() & _OPERATION_DEPRECATED) == 0: all_nicknames.append(nickname) except Error: pass type_map(gtype, add_nickname) return ffi.NULL type_map(type_from_name('VipsOperation'), add_nickname) # add 'missing' synonyms by hand all_nicknames.append('crop') # make list unique and sort all_nicknames = list(set(all_nicknames)) all_nicknames.sort() for nickname in all_nicknames: print(generate_operation(nickname, declarations_only))
def generate_operators(declarations_only=False): all_nicknames = [] def add_nickname(gtype, a, b): nickname = nickname_find(gtype) try: # can fail for abstract types intro = Introspect.get(nickname) # we are only interested in non-deprecated operations if (intro.flags & _OPERATION_DEPRECATED) == 0: all_nicknames.append(nickname) except Error: pass type_map(gtype, add_nickname) return ffi.NULL type_map(type_from_name('VipsOperation'), add_nickname) # add 'missing' synonyms by hand all_nicknames.append('crop') # make list unique and sort all_nicknames = list(set(all_nicknames)) all_nicknames.sort() for nickname in all_nicknames: print(generate_operation(nickname, declarations_only))
def add_enum(gtype, a, b): nickname = type_name(gtype) all_enums.append(nickname) type_map(gtype, add_enum) return ffi.NULL
def gen_function_list(): all_nicknames = [] def add_nickname(gtype, a, b): nickname = nickname_find(gtype) try: # can fail for abstract types op = Operation.new_from_name(nickname) # we are only interested in non-deprecated operations if (op.get_flags() & _OPERATION_DEPRECATED) == 0: all_nicknames.append(nickname) except Error: pass type_map(gtype, add_nickname) return ffi.NULL type_map(type_from_name('VipsOperation'), add_nickname) # add 'missing' synonyms by hand all_nicknames.append('crop') # make list unique and sort all_nicknames = list(set(all_nicknames)) all_nicknames.sort() for nickname in all_nicknames: gen_function(nickname)
def add_enum(gtype, a, b): nickname = type_name(gtype) all_nicknames.append(nickname) gtype_to_js_param[gtype] = f'{remove_prefix(nickname)} | Enum' type_map(gtype, add_enum) return ffi.NULL
def generate_enums_flags(file): all_enums = [] all_flags = [] def add_enum(gtype, a, b): nickname = type_name(gtype) all_enums.append(nickname) type_map(gtype, add_enum) return ffi.NULL # Enums type_map(type_from_name('GEnum'), add_enum) # Flags all_flags.append('VipsForeignPngFilter') print(f'Generating {file}...') with open(file, 'w') as f: f.write(' // Auto-generated enums\n') for name in all_enums: gtype = type_from_name(name) f.write(f' enum_<{name}>("{remove_prefix(name)}")') for value in values_for_enum(gtype): js_value = cppize(value) prefix = to_snake_case(name).upper() if prefix == 'VIPS_BAND_FORMAT': prefix = 'VIPS_FORMAT' elif prefix == 'VIPS_IMAGE_TYPE': prefix = 'VIPS_IMAGE' cpp_value = prefix + '_' + js_value.upper() if cpp_value == 'VIPS_INTERPRETATION_SRGB': cpp_value = 'VIPS_INTERPRETATION_sRGB' elif cpp_value == 'VIPS_INTERPRETATION_SCRGB': cpp_value = 'VIPS_INTERPRETATION_scRGB' f.write(f'\n .value("{js_value}", {cpp_value})') f.write(';\n\n') for name in all_flags: gtype = type_from_name(name) f.write(f' enum_<{name}>("{remove_prefix(name)}")') for value in values_for_flag(gtype): js_value = cppize(value) prefix = to_snake_case(name).upper() cpp_value = prefix + '_' + js_value.upper() f.write(f'\n .value("{js_value}", {cpp_value})') f.write(';\n\n')
def add_nickname(gtype, a, b): nickname = nickname_find(gtype) try: Operation.generate_sphinx(nickname) all_nicknames.append(nickname) except Error: pass type_map(gtype, add_nickname) return ffi.NULL
def generate_sphinx_all(): """Generate sphinx documentation. This generates a .rst file for all auto-generated image methods. Use it to regenerate the docs with something like:: $ python -c \ "import pyvips; pyvips.Operation.generate_sphinx_all()" > x And copy-paste the file contents into doc/vimage.rst in the appropriate place. """ # generate list of all nicknames we can generate docstrings for all_nicknames = [] def add_nickname(gtype, a, b): nickname = nickname_find(gtype) try: Operation.generate_sphinx(nickname) all_nicknames.append(nickname) except Error: pass type_map(gtype, add_nickname) return ffi.NULL type_map(type_from_name('VipsOperation'), add_nickname) all_nicknames.sort() # remove operations we have to wrap by hand exclude = ['scale', 'ifthenelse', 'bandjoin', 'bandrank'] all_nicknames = [x for x in all_nicknames if x not in exclude] # Output summary table print('.. class:: pyvips.Image\n') print(' .. rubric:: Methods\n') print(' .. autosummary::') print(' :nosignatures:\n') for nickname in all_nicknames: print(' ~{0}'.format(nickname)) print() # Output docs print() for nickname in all_nicknames: docstr = Operation.generate_sphinx(nickname) docstr = docstr.replace('\n', '\n ') print(' ' + docstr)
def generate_enums(): # otherwise we're missing some enums vips_lib.vips_token_get_type() vips_lib.vips_saveable_get_type() vips_lib.vips_image_type_get_type() all_enums = [] def add_enum(gtype, a, b): nickname = type_name(gtype) all_enums.append(nickname) type_map(gtype, add_enum) return ffi.NULL type_map(type_from_name('GEnum'), add_enum) for name in all_enums: gtype = type_from_name(name) python_name = remove_prefix(name) if python_name not in xml_enums: continue node = xml_enums[python_name] enum_doc = node.find("goi:doc", namespace) print(f'') print(f'') print(f'class {python_name}(object):') print(f' """{python_name}.') if enum_doc is not None: print(f'') print(f'{enum_doc.text}') print(f'') print(f'Attributes:') print(f'') for value in values_for_enum(gtype): python_name = value.replace('-', '_') member = node.find(f"goi:member[@name='{python_name}']", namespace) member_doc = member.find("goi:doc", namespace) if member_doc is not None: text = member_doc.text print(f' {python_name.upper()} (str): {text}') print(f'') print(f' """') print(f'') for value in values_for_enum(gtype): python_name = value.replace('-', '_').upper() print(f' {python_name} = \'{value}\'')
def add_nickname(gtype, a, b): nickname = nickname_find(gtype) try: # can fail for abstract types intro = Introspect.get(nickname) # we are only interested in non-deprecated operations if (intro.flags & _OPERATION_DEPRECATED) == 0: all_nicknames.append(nickname) except Error: pass type_map(gtype, add_nickname) return ffi.NULL
def add_name(gtype, a, b): if gtype in alias_gtypes: name = alias_gtypes[gtype] else: name = nickname_find(gtype) try: Operation.generate_sphinx(name) all_names.append(name) except Error: pass type_map(gtype, add_name) return ffi.NULL
def add_nickname(gtype, a, b): nickname = nickname_find(gtype) try: # can fail for abstract types op = Operation.new_from_name(nickname) # we are only interested in non-deprecated operations if (op.get_flags() & _OPERATION_DEPRECATED) == 0: all_nicknames.append(nickname) except Error: pass type_map(gtype, add_nickname) return ffi.NULL
def generate_type_declarations(filename): all_nicknames = [] def add_nickname(gtype, a, b): nickname = nickname_find(gtype) try: # can fail for abstract types intro = Introspect.get(nickname) # we are only interested in non-deprecated operations if (intro.flags & _OPERATION_DEPRECATED) == 0: all_nicknames.append(nickname) except Error: pass type_map(gtype, add_nickname) return ffi.NULL type_map(type_from_name('VipsOperation'), add_nickname) # add 'missing' synonyms by hand all_nicknames.append('crop') # make list unique and sort all_nicknames = list(set(all_nicknames)) all_nicknames.sort(key=lambda x: (bool(Introspect.get(x).member_x), x)) # filter functions we document by hand filter = [ 'composite', 'find_trim', 'profile', 'project', 'bandjoin_const', 'boolean_const', 'math2_const', 'relational_const', 'remainder_const' ] all_nicknames = [name for name in all_nicknames if name not in filter] with open(filename, 'a') as f: f.write(' class ImageAutoGen {\n') f.write( ' // THIS IS A GENERATED CLASS. DO NOT EDIT DIRECTLY.\n') for nickname in all_nicknames: f.write(generate_operation(nickname) + '\n') f.write(' }\n') f.write('}')
def generate_functions(file): all_nicknames = [] def add_nickname(gtype, a, b): nickname = nickname_find(gtype) try: # can fail for abstract types intro = Introspect.get(nickname) # we are only interested in non-deprecated operations if (intro.flags & _OPERATION_DEPRECATED) == 0: all_nicknames.append(nickname) except Error: pass type_map(gtype, add_nickname) return ffi.NULL type_map(type_from_name('VipsOperation'), add_nickname) # add 'missing' synonyms by hand all_nicknames.append('crop') # make list unique and sort all_nicknames = list(set(all_nicknames)) all_nicknames.sort(key=lambda x: (bool(Introspect.get(x).member_x), x)) # enum, _const and multiple output functions are wrapped by hand filter = [ 'add', 'bandbool', 'bandjoin_const', 'boolean', 'boolean_const', 'complex', 'complexget', 'composite', 'divide', 'find_trim', 'flip', 'linear', 'math', 'math2', 'math2_const', 'morph', 'multiply', 'profile', 'project', 'relational', 'relational_const', 'remainder', 'remainder_const', 'rot', 'round', 'subtract' ] all_nicknames = [name for name in all_nicknames if name not in filter] print(f'Generating {file}...') with open(file, 'w') as f: f.write(' // Auto-generated (class-)functions\n') for nickname in all_nicknames: f.write(generate_operation(nickname) + '\n')
def generate_enums(): # otherwise we're missing some enums vips_lib.vips_token_get_type() vips_lib.vips_saveable_get_type() vips_lib.vips_image_type_get_type() all_enums = [] def add_enum(gtype, a, b): nickname = type_name(gtype) all_enums.append(nickname) type_map(gtype, add_enum) return ffi.NULL type_map(type_from_name('GEnum'), add_enum) for name in all_enums: gtype = type_from_name(name) php_name = remove_prefix(name) print('Generating {0}.php ...'.format(php_name)) with open('{0}.php'.format(php_name), 'w') as f: f.write(preamble) f.write('\n') f.write('namespace Jcupitt\\Vips;\n') f.write('\n') f.write('/**\n') f.write(' * The {0} enum.\n'.format(php_name)) f.write(class_header) f.write(' */\n') f.write('abstract class {0}\n'.format(php_name)) f.write('{\n') for value in values_for_enum(gtype): php_name = value.replace('-', '_').upper() if php_name in reserved_php_names: php_name = reserved_php_names[php_name] f.write(' const {0} = \'{1}\';\n'.format(php_name, value)) f.write('}\n')
def generate_operators(declarations_only=False): all_nicknames = [] def add_nickname(gtype, a, b): nickname = nickname_find(gtype) try: # can fail for abstract types intro = Introspect.get(nickname) # we are only interested in non-deprecated operations if (intro.flags & _OPERATION_DEPRECATED) == 0: all_nicknames.append(nickname) except Error: pass type_map(gtype, add_nickname) return ffi.NULL type_map(type_from_name('VipsOperation'), add_nickname) # add 'missing' synonyms by hand all_nicknames.append('crop') # make list unique and sort all_nicknames = list(set(all_nicknames)) all_nicknames.sort(key=lambda x: (bool(Introspect.get(x).member_x), x)) # some functions are wrapped by hand filter = [ 'add', 'bandjoin_const', 'boolean', 'composite', 'divide', 'ifthenelse', 'math2', 'multiply', 'relational', 'remainder', 'subtract' ] all_nicknames = [name for name in all_nicknames if name not in filter] print(preamble) for nickname in all_nicknames: print(generate_operation(nickname, declarations_only))
def gen_function_list(): all_nicknames = [] def add_nickname(gtype, a, b): nickname = nickname_find(gtype) try: # can fail for abstract types intro = Introspect.get(nickname) # we are only interested in non-deprecated operations if (intro.flags & _OPERATION_DEPRECATED) == 0: all_nicknames.append(nickname) except Error: pass type_map(gtype, add_nickname) return ffi.NULL type_map(type_from_name('VipsOperation'), add_nickname) # make list unique and sort all_nicknames = list(set(all_nicknames)) all_nicknames.sort() # make dict with overloads overloads = { 'bandbool': ['bandand', 'bandor', 'bandeor', 'bandmean'], 'bandjoin': ['bandjoin2'], 'bandjoin_const': ['bandjoin_const1'], 'boolean': ['andimage', 'orimage', 'eorimage', 'lshift', 'rshift'], 'cast': ['cast_uchar', 'cast_char', 'cast_ushort', 'cast_short' 'cast_uint', 'cast_int', 'cast_float', 'cast_double', 'cast_complex', 'cast_dpcomplex'], 'complex': ['polar', 'rect', 'conj'], 'complex2': ['cross_phase'], 'complexget': ['real', 'imag'], 'draw_circle': ['draw_circle1'], 'draw_flood': ['draw_flood1'], 'draw_line': ['draw_line1'], 'draw_mask': ['draw_mask1'], 'draw_rect': ['draw_rect1', 'draw_point', 'draw_point1'], 'extract_area': ['crop'], 'linear': ['linear1'], 'math': ['sin', 'cos', 'tan', 'asin', 'acos', 'atan', 'exp', 'exp10', 'log', 'log10'], 'math2': ['pow', 'wop'], 'rank': ['median'], 'relational': ['equal', 'notequal', 'less', 'lesseq', 'more', 'moreeq'], 'remainder_const': ['remainder_const1'], 'round': ['floor', 'ceil', 'rint'], } overloads['boolean_const'] = [o + '_const' for o in overloads['boolean']] + ['boolean_const1'] + \ [o + '_const1' for o in overloads['boolean']] overloads['math2_const'] = [o + '_const' for o in overloads['boolean']] + ['math2_const1'] + \ [o + '_const1' for o in overloads['boolean']] overloads['relational_const'] = [o + '_const' for o in overloads['relational']] + ['relational_const1'] + \ [o + '_const1' for o in overloads['relational']] for nickname in all_nicknames: result = gen_function(nickname, overloads[nickname] if nickname in overloads else None) print(result)
def generate_enums_flags(gir_file, out_file): root = ET.parse(gir_file).getroot() namespace = {'goi': 'http://www.gtk.org/introspection/core/1.0'} # find all the enumerations/flags and make a dict for them xml_enums = {} for node in root.findall('goi:namespace/goi:enumeration', namespace): xml_enums[node.get('name')] = node xml_flags = {} for node in root.findall('goi:namespace/goi:bitfield', namespace): xml_flags[node.get('name')] = node all_nicknames = [] def add_enum(gtype, a, b): nickname = type_name(gtype) all_nicknames.append(nickname) gtype_to_js_param[gtype] = f'{remove_prefix(nickname)} | Enum' type_map(gtype, add_enum) return ffi.NULL # Enums type_map(type_from_name('GEnum'), add_enum) # Flags all_nicknames.append('VipsForeignPngFilter') gtype_to_js_param[ type_from_name('VipsForeignPngFilter' )] = f'{remove_prefix("VipsForeignPngFilter")} | Flag' with open('preamble_vips.d.ts', 'r') as f: preamble = f.read() with open(out_file, 'w') as f: f.write(preamble) for name in all_nicknames: gtype = type_from_name(name) name = remove_prefix(name) if name in xml_enums: is_enum = True node = xml_enums[name] elif name in xml_flags: is_enum = False node = xml_flags[name] else: continue enum_doc = node.find('goi:doc', namespace) if enum_doc is not None: text = enum_doc.text.replace('\n', '\n * ') f.write(' /**\n') f.write(f" * {text}\n") f.write(' */\n') f.write(f' export enum {name} {{\n') values = values_for_enum(gtype) if is_enum else values_for_flag( gtype) for i, value in enumerate(values): js_value = value.replace('-', '_') if i == 0 and (js_value == 'error' or js_value == 'notset'): continue member = node.find(f"goi:member[@name='{js_value}']", namespace) member_doc = member.find('goi:doc', namespace) if member_doc is not None: text = member_doc.text[:1].upper() + member_doc.text[1:] f.write(' /**\n') f.write(f' * {text}\n') f.write(' */\n') f.write(f" {js_value} = '{value}'") if i != len(values) - 1: f.write(',\n') f.write('\n }\n\n')
def generate_auto_doc(filename): all_nicknames = [] def add_nickname(gtype, a, b): nickname = nickname_find(gtype) try: # can fail for abstract types op = Operation.new_from_name(nickname) # we are only interested in non-deprecated operations if (op.get_flags() & _OPERATION_DEPRECATED) == 0: all_nicknames.append(nickname) except Error: pass type_map(gtype, add_nickname) return ffi.NULL type_map(type_from_name('VipsOperation'), add_nickname) # add 'missing' synonyms by hand all_nicknames.append('crop') # make list unique and sort all_nicknames = list(set(all_nicknames)) all_nicknames.sort() # these have hand-written methods, don't autodoc them no_generate = [ 'bandjoin', 'bandrank', 'ifthenelse', 'add', 'subtract', 'multiply', 'divide', 'remainder' ] all_nicknames = [x for x in all_nicknames if x not in no_generate] print('Generating {0} ...'.format(filename)) with open(filename, 'w') as f: f.write(preamble) f.write('\n') f.write('namespace Jcupitt\\Vips;\n') f.write('\n') f.write('/**\n') f.write(' * Autodocs for the Image class.\n') f.write(class_header) f.write(' *\n') for nickname in all_nicknames: f.write(generate_operation(nickname)) f.write(' *\n') # all magic properties tmp_file = Image.new_temp_file('%s.v') all_properties = tmp_file.get_fields() for name in all_properties: php_name = name.replace('-', '_') gtype = tmp_file.get_typeof(name) fundamental = gobject_lib.g_type_fundamental(gtype) f.write(' * @property {0} ${1} {2}\n'.format( gtype_to_php(gtype), php_name, tmp_file.get_blurb(name))) if fundamental == GValue.genum_type: f.write(' * @see {0} for possible values\n'.format( remove_prefix(type_name(gtype)))) f.write(' */\n') f.write('abstract class ImageAutodoc\n') f.write('{\n') f.write('}\n')