SM2Gen/json5_fix_format.py

96 lines
2.9 KiB
Python

import re
import json5
def fix_json5_syntax(text):
# Remove comments
text = re.sub(r'//.*', '', text)
text = re.sub(r'/\*.*?\*/', '', text, flags=re.DOTALL)
# Replace single quotes with double quotes
text = re.sub(r"'", '"', text)
# Add missing commas between objects in arrays (naive)
text = re.sub(r'(\})(\s*\{)', r'\1,\2', text)
# Remove trailing commas before closing } or ]
text = re.sub(r',(\s*[}\]])', r'\1', text)
return text
def renumber_inputs(obj, start=100):
"""
Recursively renumber InputN keys to Input{start}, Input{start+1}, ...
Returns the new object and the next available number.
"""
if isinstance(obj, dict):
new_obj = {}
for k, v in obj.items():
m = re.match(r'Input(\d+)', k)
if m:
new_key = f"Input{start}"
start += 1
else:
new_key = k
new_obj[new_key], start = renumber_inputs(v, start)
return new_obj, start
elif isinstance(obj, list):
new_list = []
for item in obj:
new_item, start = renumber_inputs(item, start)
new_list.append(new_item)
return new_list, start
else:
return obj, start
def dict_to_json5(obj, indent=0):
"""Convert a dict to JSON5-like text with unquoted field names."""
IND = ' '
if isinstance(obj, dict):
items = []
for k, v in obj.items():
# Only quote keys if necessary (not a valid identifier)
if re.match(r'^[A-Za-z_]\w*$', k):
key = k
else:
key = f'"{k}"'
items.append(f"{IND* (indent+1)}{key}: {dict_to_json5(v, indent+1)}")
return '{\n' + ',\n'.join(items) + f'\n{IND*indent}' + '}'
elif isinstance(obj, list):
items = [f"{IND*(indent+1)}{dict_to_json5(v, indent+1)}" for v in obj]
return '[\n' + ',\n'.join(items) + f'\n{IND*indent}' + ']'
elif isinstance(obj, str):
# Always single-quote strings for JSON5 style
return "'" + obj.replace("'", "\\'") + "'"
elif obj is True:
return 'true'
elif obj is False:
return 'false'
elif obj is None:
return 'null'
else:
return str(obj)
def main():
input_file = 'json5/shared-folders.json5'
output_file = 'json5/shared-folders-renumbered.json5'
# Read and fix the JSON5 input
with open(input_file, 'r', encoding='utf-8') as f:
raw = f.read()
fixed = fix_json5_syntax(raw)
# Parse with json5
try:
data = json5.loads(fixed)
except Exception as e:
print("Error parsing JSON5:", e)
return
# Renumber Input fields
data, _ = renumber_inputs(data, 100)
# Write out as JSON5 with unquoted field names
with open(output_file, 'w', encoding='utf-8') as f:
f.write(dict_to_json5(data, indent=0))
print(f"Renumbered file written to: {output_file}")
if __name__ == '__main__':
main()