updates
This commit is contained in:
@@ -24,7 +24,6 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
/* Load link with relative path */
|
|
||||||
Math3200_link: {
|
Math3200_link: {
|
||||||
title: 'Math3200',
|
title: 'Math3200',
|
||||||
type: 'page',
|
type: 'page',
|
||||||
|
|||||||
@@ -2,19 +2,22 @@
|
|||||||
"""
|
"""
|
||||||
This code is generate by ChatGPT 5.1, as test automatic script to generate _meta.js file
|
This code is generate by ChatGPT 5.1, as test automatic script to generate _meta.js file
|
||||||
|
|
||||||
Generate _meta.js with Math/CSE link entries and labeled sections
|
Generate ./docker/_meta.js with Math/CSE link entries and labeled sections
|
||||||
from the original _meta.js.
|
from ./content/_meta.js.
|
||||||
|
|
||||||
Usage:
|
This script is intended to be run directly (no arguments) from anywhere.
|
||||||
python generate_meta.py [path/to/_meta.js]
|
|
||||||
|
|
||||||
If no path is given, it assumes _meta.js is next to this script.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import sys
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------
|
||||||
|
# Configuration
|
||||||
|
# --------------------------------------------------------------------
|
||||||
|
|
||||||
|
SCRIPT_DIR = Path(__file__).resolve().parent
|
||||||
|
SRC_META = SCRIPT_DIR.parent / "content" / "_meta.js"
|
||||||
|
DST_META = SCRIPT_DIR / "_meta.js"
|
||||||
|
|
||||||
COMMENT_BLOCK = [
|
COMMENT_BLOCK = [
|
||||||
" /**\n",
|
" /**\n",
|
||||||
@@ -26,56 +29,62 @@ COMMENT_BLOCK = [
|
|||||||
" */\n",
|
" */\n",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
PROP_RE = re.compile(r"^ {4}(\w+)\s*:")
|
||||||
|
|
||||||
|
|
||||||
def parse_properties(lines):
|
def parse_properties(lines):
|
||||||
"""
|
"""
|
||||||
Parse top-level properties (indented 4 spaces) of the export default object.
|
Parse top-level properties (indented 4 spaces) of the export default object.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
header_lines: lines up to and including 'export default {'
|
header_lines: lines up to and including 'export default {'
|
||||||
footer_lines: closing '}' (and anything after)
|
footer_lines: closing '}' (and anything after)
|
||||||
props: dict name -> list of lines for that property
|
props: dict name -> list of lines for that property
|
||||||
order: order of property names as they appeared
|
order: order of property names as they appeared
|
||||||
"""
|
"""
|
||||||
# find 'export default {' line
|
|
||||||
export_idx = None
|
export_idx = None
|
||||||
for i, line in enumerate(lines):
|
for i, line in enumerate(lines):
|
||||||
if "export default" in line:
|
if "export default" in line:
|
||||||
export_idx = i
|
export_idx = i
|
||||||
break
|
break
|
||||||
if export_idx is None:
|
if export_idx is None:
|
||||||
raise ValueError("No 'export default' found in file.")
|
raise ValueError("No 'export default' found in source meta file.")
|
||||||
|
|
||||||
|
# find closing brace of the object (typically last non-empty '}' line)
|
||||||
|
closing_idx = None
|
||||||
|
for i in range(len(lines) - 1, -1, -1):
|
||||||
|
if lines[i].strip().startswith("}"):
|
||||||
|
closing_idx = i
|
||||||
|
break
|
||||||
|
if closing_idx is None or closing_idx <= export_idx:
|
||||||
|
raise ValueError("Could not locate closing '}' of export default object.")
|
||||||
|
|
||||||
header = lines[: export_idx + 1]
|
header = lines[: export_idx + 1]
|
||||||
body = lines[export_idx + 1 :]
|
footer = lines[closing_idx:]
|
||||||
|
body = lines[export_idx + 1 : closing_idx]
|
||||||
|
|
||||||
# last non-empty line is closing brace of the object
|
|
||||||
last_non_empty = len(lines) - 1
|
|
||||||
while last_non_empty >= 0 and lines[last_non_empty].strip() == "":
|
|
||||||
last_non_empty -= 1
|
|
||||||
footer = lines[last_non_empty:]
|
|
||||||
|
|
||||||
body_until_footer = body[: len(body) - len(footer) + 1] # include blank before footer if any
|
|
||||||
|
|
||||||
prop_re = re.compile(r"^ {4}(\w+)\s*:")
|
|
||||||
props = {}
|
props = {}
|
||||||
order = []
|
order = []
|
||||||
|
|
||||||
i = 0
|
i = 0
|
||||||
n = len(body_until_footer)
|
n = len(body)
|
||||||
while i < n:
|
while i < n:
|
||||||
line = body_until_footer[i]
|
line = body[i]
|
||||||
m = prop_re.match(line)
|
m = PROP_RE.match(line)
|
||||||
if not m:
|
if not m:
|
||||||
i += 1
|
i += 1
|
||||||
continue
|
continue
|
||||||
|
|
||||||
key = m.group(1)
|
key = m.group(1)
|
||||||
start = i
|
start = i
|
||||||
|
|
||||||
brace_count = line.count("{") - line.count("}")
|
brace_count = line.count("{") - line.count("}")
|
||||||
j = i + 1
|
j = i + 1
|
||||||
while j < n and brace_count > 0:
|
while j < n and brace_count > 0:
|
||||||
brace_count += body_until_footer[j].count("{") - body_until_footer[j].count("}")
|
brace_count += body[j].count("{") - body[j].count("}")
|
||||||
j += 1
|
j += 1
|
||||||
block = body_until_footer[start:j]
|
|
||||||
|
block = body[start:j]
|
||||||
props[key] = block
|
props[key] = block
|
||||||
order.append(key)
|
order.append(key)
|
||||||
i = j
|
i = j
|
||||||
@@ -100,10 +109,13 @@ def generate_new_meta(lines):
|
|||||||
|
|
||||||
math_keys = [k for k in order if k.startswith("Math")]
|
math_keys = [k for k in order if k.startswith("Math")]
|
||||||
cse_keys = [k for k in order if k.startswith("CSE")]
|
cse_keys = [k for k in order if k.startswith("CSE")]
|
||||||
other_keys = [k for k in order if k not in math_keys + cse_keys + ["menu"]]
|
other_keys = [
|
||||||
|
k for k in order
|
||||||
|
if k not in math_keys + cse_keys + ["menu"]
|
||||||
|
]
|
||||||
|
|
||||||
if "menu" not in props:
|
if "menu" not in props:
|
||||||
raise ValueError("Expected a top-level 'menu' property.")
|
raise ValueError("Expected a top-level 'menu' property in source meta.")
|
||||||
|
|
||||||
out = []
|
out = []
|
||||||
|
|
||||||
@@ -111,7 +123,7 @@ def generate_new_meta(lines):
|
|||||||
out.extend(header)
|
out.extend(header)
|
||||||
# comment block
|
# comment block
|
||||||
out.extend(COMMENT_BLOCK)
|
out.extend(COMMENT_BLOCK)
|
||||||
# menu
|
# original menu block
|
||||||
out.extend(props["menu"])
|
out.extend(props["menu"])
|
||||||
|
|
||||||
# Math links
|
# Math links
|
||||||
@@ -142,20 +154,15 @@ def generate_new_meta(lines):
|
|||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
||||||
def main():
|
# --------------------------------------------------------------------
|
||||||
if len(sys.argv) > 1:
|
# Script execution (no CLI args, no main())
|
||||||
meta_path = Path(sys.argv[1]).resolve()
|
# --------------------------------------------------------------------
|
||||||
else:
|
|
||||||
meta_path = Path(__file__).with_name("_meta.js")
|
|
||||||
|
|
||||||
if not meta_path.exists():
|
if not SRC_META.exists():
|
||||||
raise SystemExit(f"Meta file not found: {meta_path}")
|
raise SystemExit(f"Source meta file not found: {SRC_META}")
|
||||||
|
|
||||||
lines = meta_path.read_text(encoding="utf-8").splitlines(keepends=True)
|
src_lines = SRC_META.read_text(encoding="utf-8").splitlines(keepends=True)
|
||||||
new_lines = generate_new_meta(lines)
|
new_lines = generate_new_meta(src_lines)
|
||||||
meta_path.write_text("".join(new_lines), encoding="utf-8")
|
DST_META.write_text("".join(new_lines), encoding="utf-8")
|
||||||
print(f"Rewrote meta file at {meta_path}")
|
|
||||||
|
|
||||||
|
print(f"Generated meta file: {DST_META}")
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
|
|||||||
Reference in New Issue
Block a user