# SPDX-FileCopyrightText: 2023 Blender Authors # # SPDX-License-Identifier: GPL-2.0-or-later ''' RNA Manual Reference Mapping Updater This script generates a file that maps RNA strings to online URL's for the context menu documentation access. This script either downloads a sphinx requirement file from the manual or optionally can take a path to the file using `--input`. To make international, we made a script, pointing the manuals to the proper language, specified in the 'User Preferences Window' by the users. Some Languages have their manual page, using a prefix or being preceded by their respective reference, for example: manual/ --> manual/ru/ The table in the script, contains all of the languages we have in the Blender manual website, for those other languages that still does not have a team of translators, and/or don't have a manual for their languages we commented the lines below, you should add them to the language table when they have a proper manual, or added to the Blender UI translation table. URL is the: url_manual_prefix + url_manual_mapping[#id] ''' import os import argparse import re import sys import datetime try: import sphobjinv except ImportError: print("The module \"sphobjinv\" was not found, it may be installed via \"pip install sphobjinv\", exiting!") sys.exit(1) # The root of Blender's source directory. BASE_DIR = os.path.join(os.path.dirname(__file__), "..", "..") # Names that don't match this regex can't be used as URL's. re_name_sanity_match = re.compile("[a-zA-Z0-9._*]+") def sphobjinv_sanity_check(o): """ Ensure ``o`` can be used to make a URL. """ name = o.name # Perhaps other characters could be excluded too. if not re_name_sanity_match.fullmatch(name): m = re_name_sanity_match.match(name) fail_char = 0 if m: fail_char = m.span(0)[1] msg = "WARNING: invalid char found for name:" print(msg, name, "(at index {:d})".format(fail_char), "skipping!") print(" " * (len(msg) + fail_char), "^") return False if " " in name or "/" in name: return False return True def write_mappings(inv, output): print("Writing...") # Write the file file = open(output, "w", encoding="utf-8") fw = file.write year = datetime.date.today().year fw("# SPDX-FileCopyrightText: 2019-{:d} Blender Authors\n".format(year)) fw("#\n") fw("# SPDX-License-Identifier: GPL-2.0-or-later\n") fw("\n") fw("# Do not edit this file. This file is auto generated from:\n") fw("# ./tools/utils_doc/rna_manual_reference_updater.py\n\n") # Prevent systems with autopep8 configured from re-formatting the file. fw("# autopep8: off\n") fw( "import bpy\n" "\n" "url_manual_prefix = \"https://docs.blender.org/manual/{:s}/{:d}.{:d}/\".format(\n" " bpy.utils.manual_language_code(),\n" " *bpy.app.version[:2],\n" ")\n" "\n" ) fw("url_manual_mapping = (\n") # Logic to manipulate strings from objects.inv lines = [ o.data_line() for o in inv.objects if o.name.startswith(("bpy.types", "bpy.ops")) if sphobjinv_sanity_check(o) ] # Finding first space will return length of rna path lines.sort(key=lambda l: l.find(" "), reverse=True) for line in lines: split = line.split(" ") fw(" (\"" + split[0] + "*\", \"" + split[3] + "\"),\n") fw(")\n\n") fw("# autopep8: on\n") def is_valid_file(parser, arg): if not os.path.isfile(arg): parser.error("The file {:s} does not exist!".format(arg)) else: return arg def main(): parser = argparse.ArgumentParser( usage=__doc__ ) parser.add_argument( "--input", dest="filename", required=False, help="sphinx inventory file (objects.inv)", metavar="FILE", type=lambda x: is_valid_file(parser, x)) parser.add_argument( "--output", dest="output", default=os.path.join(BASE_DIR, "scripts", "modules", "rna_manual_reference.py"), required=False, help="path to output including filename and extentsion", metavar="FILE") parser.add_argument( "--url", dest="url", default="https://docs.blender.org/manual/en/dev/objects.inv", required=False, help="url to sphinx inventory file (objects.inv)", metavar="FILE") args = parser.parse_args() if args.filename: # Download and decode objects.inv print("Loading from file...") inv = sphobjinv.Inventory(args.filename) else: # Load and decode objects.inv print("Downloading...") inv = sphobjinv.Inventory(url=args.url) write_mappings(inv, args.output) print("Done!") if __name__ == "__main__": main()