mirror of
https://github.com/godotengine/godot-docs.git
synced 2025-12-31 17:49:03 +03:00
Add a tool to move rst files and images
The program moves a list of rst files along with their image dependencies to a target directory. It then outputs redirects in the format the ReadTheDocs backend expects.
This commit is contained in:
108
_tools/move_rst_files.py
Normal file
108
_tools/move_rst_files.py
Normal file
@@ -0,0 +1,108 @@
|
||||
import re
|
||||
from argparse import ArgumentParser
|
||||
from os.path import isfile, isdir, join, realpath, split, dirname, relpath
|
||||
import os
|
||||
import shutil
|
||||
|
||||
|
||||
def parse_and_get_arguments():
|
||||
"""Creates and returns an object with parsed arguments, using argparse."""
|
||||
parser: ArgumentParser = ArgumentParser(
|
||||
prog="move_rst_files",
|
||||
description="Moves reST documents and their dependencies from one folder to another. Outputs required redirections in the ReadTheDocs backend.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"documents", nargs="+", help="Paths of documents to move.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"output_path", help="Path to the target output directory.",
|
||||
)
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def find_project_root_path(document_path):
|
||||
"""Returns the path to the repository's root directory by looking for the file conf.py, starting
|
||||
from the path of any file in the project."""
|
||||
full_path = realpath(document_path)
|
||||
dirpath = split(full_path)[0]
|
||||
|
||||
root_path = ""
|
||||
current = dirpath
|
||||
iterations = 0
|
||||
while root_path == "":
|
||||
if isfile(join(current, "conf.py")):
|
||||
root_path = current
|
||||
else:
|
||||
current = split(current)[0]
|
||||
if current == "":
|
||||
break
|
||||
iterations += 1
|
||||
if iterations > 20:
|
||||
break
|
||||
return root_path
|
||||
|
||||
|
||||
def find_images(document):
|
||||
"""Returns the list of image filepaths used by the `document`."""
|
||||
images = []
|
||||
for line in document:
|
||||
match = re.match(r"\.\. image::\s+(img\/.+)", line)
|
||||
if match:
|
||||
images.append(match[1])
|
||||
return list(set(images))
|
||||
|
||||
|
||||
def find_document_dependencies(documents):
|
||||
"""For each document path in `documents`, finds all pictures it depends on and returns a dict with the form { document: [images] }."""
|
||||
data = {}
|
||||
for path in documents:
|
||||
with open(path, "r") as rst_file:
|
||||
images = find_images(rst_file)
|
||||
data[path] = images
|
||||
return data
|
||||
|
||||
|
||||
def move_documents(paths, output_path):
|
||||
"""Moves .rst files and all their image dependencies to `output_path`"""
|
||||
data = find_document_dependencies(paths)
|
||||
for path in data:
|
||||
directory = dirname(path)
|
||||
shutil.move(path, output_path)
|
||||
for image in data[path]:
|
||||
image_in_path = join(directory, image)
|
||||
image_out_path = join(output_path, image)
|
||||
image_out_dirpath = dirname(image_out_path)
|
||||
if not isdir(image_out_dirpath):
|
||||
os.makedirs(image_out_dirpath)
|
||||
shutil.move(image_in_path, image_out_path)
|
||||
|
||||
|
||||
def print_redirects(paths):
|
||||
"""Prints redirects we need to make on the ReadTheDocs backend with the form "input -> output".
|
||||
Moving the file /learning/features/viewports/viewports.rst to /tutorials/viewports/viewports.rst
|
||||
Requires the following redirect:
|
||||
/learning/features/viewports/viewports.html -> /tutorials/viewports/viewports.html
|
||||
"""
|
||||
redirects = ""
|
||||
project_root_path = find_project_root_path(paths[0])
|
||||
out_path_relative = relpath(args.output_path, project_root_path)
|
||||
for document in paths:
|
||||
in_path_relative = relpath(document, project_root_path)
|
||||
in_directory, filename_rst = split(in_path_relative)
|
||||
filename_html = filename_rst.rsplit(".rst", 1)[0] + ".html"
|
||||
|
||||
in_path = join(in_directory, filename_html)
|
||||
out_path = join(out_path_relative, filename_html)
|
||||
redirects += in_path + " -> " + out_path + "\n"
|
||||
print(redirects)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
args = parse_and_get_arguments()
|
||||
assert isdir(args.output_path)
|
||||
|
||||
documents = [
|
||||
path for path in args.documents if isfile(path) and path.endswith(".rst")
|
||||
]
|
||||
move_documents(documents, args.output_path)
|
||||
print_redirects(documents)
|
||||
Reference in New Issue
Block a user