-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
plot-updates.py
149 lines (127 loc) · 6.11 KB
/
plot-updates.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# Ministry of Futility
# Copyright (C) 2024 Mathew Mytka - m3metix
# This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
# You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
import os
import re
# Directory to save generated JS files
output_dir = "static/js/scenes/"
# Ensure the output directory exists
os.makedirs(output_dir, exist_ok=True)
# Regular expressions to match scenes, titles, context, and choices
scene_re = re.compile(r"^##\s+(.+)$")
title_re = re.compile(r"^title:\s+;(.*);$")
location_re = re.compile(r"^location:\s+;(.*);$")
scene_description_re = re.compile(r"^scene description:\s+;(.*);$")
context_re = re.compile(r"^context:\s+;(.*);$")
choice_re = re.compile(r"-\s+(.*):\s+(.*?)(?:;\s*(.*))?$")
# Initialize variables
current_scene = None
scenes = {}
in_plot_section = False # Track if we're inside the PLOT_START/PLOT_END section
def normalize_scene_name(scene_name):
# Lowercase all words and join them with hyphens
words = scene_name.split()
normalized_name = '-'.join(word.lower() for word in words)
return normalized_name
def escape_quotes(text):
# Escape single quotes for JavaScript
return text.replace("'", "\\'")
# Read the Plot.md file
with open("Plot.md", "r") as file:
for i, line in enumerate(file, start=1):
# Check for PLOT_START and PLOT_END markers
if line.strip() == "# PLOT_START":
in_plot_section = True
continue
elif line.strip() == "# PLOT_END":
in_plot_section = False
continue
# Only process lines within the PLOT_START/PLOT_END section
if in_plot_section:
try:
# Match a scene
match = scene_re.match(line)
if match:
current_scene = normalize_scene_name(escape_quotes(match.group(1).strip()))
scenes[current_scene] = {
"title": "",
"location": "",
"sceneDescription": "",
"context": "",
"choices": []
}
continue
# Match a title
match = title_re.match(line)
if match and current_scene:
scenes[current_scene]["title"] = escape_quotes(match.group(1).strip())
continue
# Match a location
match = location_re.match(line)
if match and current_scene:
scenes[current_scene]["location"] = escape_quotes(match.group(1).strip())
continue
# Match a scene description
match = scene_description_re.match(line)
if match and current_scene:
scenes[current_scene]["sceneDescription"] = escape_quotes(match.group(1).strip())
continue
# Match a context
match = context_re.match(line)
if match and current_scene:
scenes[current_scene]["context"] = escape_quotes(match.group(1).strip())
continue
# Match a choice with an optional action
match = choice_re.match(line)
if match and current_scene:
choice_text = escape_quotes(match.group(1).strip())
choice_target = 'null' if match.group(2).strip().lower() == 'none' else normalize_scene_name(match.group(2).strip())
choice_actions = [act.strip() for act in match.group(3).split(',')] if match.group(3) else []
scenes[current_scene]["choices"].append({
"text": choice_text,
"target": choice_target,
"actions": choice_actions
})
except ValueError as ve:
print(f"Error processing line {i}: {line.strip()}")
print(f"ValueError: {ve}")
raise
except Exception as e:
print(f"Unexpected error processing line {i}: {line.strip()}")
print(f"Exception: {e}")
raise
# Generate JS files
for scene, data in scenes.items():
js_file_path = os.path.join(output_dir, f"{normalize_scene_name(scene)}.js")
existing_code = ""
# Read existing file to preserve custom code
if os.path.exists(js_file_path):
with open(js_file_path, "r") as js_file:
inside_scene_content = False
for line in js_file:
if "window.sceneContent" in line:
inside_scene_content = True
if inside_scene_content and line.strip() == "`;":
inside_scene_content = False
continue
if not inside_scene_content:
existing_code += line
# Prepare new scene content
js_content = f"window.sceneContent = {{\n"
js_content += f" title: '{data['title']}',\n"
js_content += f" location: '{data['location']}',\n"
js_content += f" sceneDescription: '{data['sceneDescription']}',\n"
js_content += f" context: '{data['context']}',\n"
js_content += f" choices: [\n"
for choice in data["choices"]:
actions = ', '.join([f"'{act}'" for act in choice["actions"]])
js_content += f" {{ text: '{choice['text']}', target: '{choice['target']}', actions: [{actions}] }},\n"
js_content += f" ]\n"
js_content += f"}};\n"
# Write the new content plus the preserved code
with open(js_file_path, "w") as js_file:
js_file.write(js_content + existing_code)
print("Scene files updated successfully.")