Last active
June 26, 2021 21:53
-
-
Save SnowyMouse/0fe2f8d9f60430c0fd1a847cd5f4287f to your computer and use it in GitHub Desktop.
Parse an hs_doc.txt file and output a JSON file
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# genscriptdefs.py by Snowy Mouse (2021) | |
# | |
# Parses an hs_doc.txt file (from using script_doc) and outputs a JSON file to | |
# be used with a tool | |
# | |
# Note that this will specifically ignore begin, begin_random, set, cond, if, | |
# and any passthrough functions, as these are written in a way that can't really | |
# be automatically parsed. (The parameter text is probably handwritten) | |
# | |
# This script is licensed under version 3 of the GNU General Public License as | |
# published by the Free Software Foundation. For more information, you can read | |
# the license here: | |
# | |
# https://www.gnu.org/licenses/gpl-3.0.en.html | |
# | |
import sys | |
import json | |
# Check to make sure we have our arguments | |
if len(sys.argv) != 3: | |
print("Usage: {} <hs_doc.txt> <output.json>".format(sys.argv[0])) | |
sys.exit(1) | |
# Read the text file line-by-line and use rstrip on each line to remove newlines | |
with open(sys.argv[1]) as f: | |
lines = [i.rstrip() for i in f.readlines()] | |
# Set these here | |
scripts = [] | |
globals = None | |
last_script = None | |
# Go through each line | |
for m in lines: | |
# Ignore empty lines | |
if len(m) == 0: | |
continue | |
# If it starts with a left parenthesis, then it's a script/global | |
if m[0] == "(": | |
# If we aren't parsing globals yet, add it to the scripts list | |
if globals is None: | |
last_script = len(scripts) | |
scripts.append([m, None]) | |
# If we are parsing globals, add it to the globals | |
else: | |
globals.append([m, None]) | |
# Next line | |
continue | |
# If the line is this, we start parsing globals then | |
if m == "; AVAILABLE EXTERNAL GLOBALS:": | |
globals = [] | |
last_script = None | |
# If it starts with a semicolon, it's a comment. But hs_doc.txt also has descriptions commented after the command. | |
if m[0] == ";" and last_script is not None: | |
scripts[last_script][1] = m | |
last_script = None | |
continue | |
# Function to further process an array of scripts or globals | |
def parse_array(what): | |
# Start with an empty array to return later | |
rv = [] | |
# Go through each object | |
for i in what: | |
# Remove the parenthesis and split into words on space | |
stripped = i[0][1:len(i[0])-1].split(" ") | |
value = { | |
# Name is the 2nd object | |
"name": stripped[1], | |
# Type is the 1st object - remove the angle brackets | |
"type": stripped[0][1:len(stripped[0])-1] | |
} | |
# We can't really handle these nicely in an automated way so don't include them | |
if value["name"] == "begin" or value["name"] == "set" or value["name"] == "cond" or value["name"] == "if" or value["name"] == "begin_random": | |
continue | |
# If we have a description, set it (remove the first two characters since it's a semicolon and space) | |
if i[1] is not None: | |
value["description"] = i[1][2:] | |
# If we have more than three words, this thing takes parameters then! | |
if len(stripped) >= 3: | |
params = [] | |
# Go through each parameter | |
for n_raw in stripped[2:]: | |
n = n_raw | |
param = {} | |
if n[0] == "[": | |
n = n[1:len(n)-1] | |
param["optional"] = True | |
# Remove the brackets | |
value_bracketless = n[1:len(n)-1] | |
# If it ends with "(s)" then it can be multiple values of the same type that go here | |
if value_bracketless.endswith("(s)"): | |
value_bracketless = value_bracketless.replace("(s)", "") | |
param["many"] = True | |
# And here's the final type | |
param["type"] = value_bracketless | |
# Add it | |
params.append(param) | |
# Set our parameters to this | |
value["parameters"] = params | |
# Add our object | |
rv.append(value) | |
# Return the array - we're done | |
return rv | |
# Process scripts and globals here | |
parsed = { | |
"scripts": parse_array(scripts), | |
"globals": parse_array(globals) | |
} | |
# Write it with four whitespace idents (not necessary and costs space, but it makes the output look pretty) | |
with open(sys.argv[2], "w") as f: | |
f.write(json.dumps(parsed, indent=" ") + "\n") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment