import json path = "/home/quant/.local/share/Steam/steamapps/common/Noita/tools_modding/lua_api_documentation.html" lines = open(path).readlines() lines_iter = iter(lines) parsed = [] def maybe_map_types(name, typ): if typ == "multiple types": raise ValueError("no 'multiple types' either") if name == "entity_id": typ = "entity_id" if name == "component_id": typ = "component_id" if typ == "float": typ = "number" if typ == "uint": typ = "color" if typ == "uint32": typ = "color" if typ == "name": typ = "string" if typ == "bool_is_new": typ = "bool" if typ == "boolean": typ = "bool" return typ def parse_arg(arg_s): if "|" in arg_s: raise ValueError("multiple argument types not supported") if "{" in arg_s: raise ValueError("no table support for now") if "multiple_types" in arg_s: raise ValueError("no 'multiple_types' either") other, *default = arg_s.split("=", maxsplit=1) other = other.strip() if default: default = default[0].strip() else: default = None name, typ = other.split(":", maxsplit=1) typ = maybe_map_types(name, typ) return { "name": name, "typ": typ, "default": default, } def parse_ret(ret_s): if not ret_s: return None optional = ret_s.endswith("|nil") ret_s = ret_s.removesuffix("|nil") if "|" in ret_s: raise ValueError("multiple return types not supported") if "{" in ret_s: raise ValueError("tables in returns not supported") if "multiple_types" in ret_s: raise ValueError("no 'multiple_types' either") typ = ret_s name = None if ":" in ret_s: name, typ = ret_s.split(":", maxsplit=1) if typ.endswith(" -"): optional = True typ = typ.removesuffix(" -") typ = maybe_map_types(name, typ) return { "name": name, "typ": typ, "optional": optional } ignore = { # Those have some specifics that make generic way of handling things not work on them "PhysicsApplyForceOnArea", "GetRandomActionWithType", "GetParallelWorldPosition", "EntityGetFirstHitboxCenter", "InputGetJoystickAnalogStick", "PhysicsAddBodyImage", "PhysicsBodyIDGetBodyAABB", "GuiTextInput", } skipped = 0 deprecated = 0 # 2 lazy 2 parse xml properly try: while True: line = next(lines_iter) if line.startswith('