swo/py/ref.py

111 lines
3.6 KiB
Python
Raw Normal View History

2025-03-30 14:21:21 +02:00
import re
import json
import sys
def build_label_dictionary(struct_json_file):
"""
Wczytuje plik .json z drzewem (type, numbering, label, children)
i tworzy słownik mapujący 'itm:xxx' -> '...numbering...'.
"""
with open(struct_json_file, 'r', encoding='utf-8') as f:
data = json.load(f)
label_map = {}
def traverse(nodes):
for node in nodes:
lbl = node.get('label', '')
if lbl.startswith('itm:'):
# np. 'itm:srodroczna-terminy'
numbering = node.get('numbering', '')
label_map[lbl] = numbering
# rekurencja po dzieciach
if 'children' in node and isinstance(node['children'], list):
traverse(node['children'])
traverse(data)
return label_map
def replace_refs_in_tex(tex_in, tex_out, label_dict):
with open(tex_in, 'r', encoding='utf-8') as f:
lines = f.readlines()
# Regex sprawdza, czy występuje opcjonalny nawias otwierający,
# polecenie \ref{itm:...}, i opcjonalny nawias zamykający.
# - group(1) => '[' lub None
# - group(2) => 'itm:...' (np. 'itm:srodroczna-terminy')
# - group(3) => ']' lub None
pattern = re.compile(r'(\[)?\\ref\{(itm:[^}]+)\}(\])?')
def ref_replacer(match):
bracket_open = match.group(1) # '[' albo None
key = match.group(2) # np. 'itm:srodroczna-terminy'
bracket_close = match.group(3) # ']' albo None
if key in label_dict:
numbering = label_dict[key]
# zamieniamy na \hyperref[itm:xxx]{numbering} bez nawiasów kwadratowych
return f"\\hyperref[{key}]{{{numbering}}}"
else:
# brak w słowniku -> zostawiamy oryginalny zapis
# (wraz z ewentualnymi nawiasami)
left = bracket_open if bracket_open else ''
right = bracket_close if bracket_close else ''
return f"{left}\\ref{{{key}}}{right}"
new_lines = []
for line in lines:
new_line = pattern.sub(ref_replacer, line)
new_lines.append(new_line)
with open(tex_out, 'w', encoding='utf-8') as f:
f.writelines(new_lines)
def main():
# Domyślne nazwy plików:
default_struct_json = "../main-struct.json"
default_tex_in = "../main.tex"
default_tex_out = "../m.tex"
args = sys.argv[1:]
if len(args) == 0:
# brak argumentów -> używamy domyślnych
struct_json_file = default_struct_json
tex_in_file = default_tex_in
tex_out_file = default_tex_out
elif len(args) == 1:
# 1 argument (plik .json), rest domyślny
struct_json_file = args[0]
tex_in_file = default_tex_in
tex_out_file = default_tex_out
elif len(args) == 2:
# 2 argumenty: .json + .tex (in), out = m.tex
struct_json_file = args[0]
tex_in_file = args[1]
tex_out_file = default_tex_out
elif len(args) == 3:
# 3 argumenty: .json + .tex(in) + .tex(out)
struct_json_file = args[0]
tex_in_file = args[1]
tex_out_file = args[2]
else:
print("Użycie:")
print(" python script.py # domyślne: ../main-struct.json, ../main.tex => m.tex")
print(" python script.py PLIK.json")
print(" python script.py PLIK.json in.tex")
print(" python script.py PLIK.json in.tex out.tex")
sys.exit(1)
label_map = build_label_dictionary(struct_json_file)
replace_refs_in_tex(tex_in_file, tex_out_file, label_map)
print(f"Gotowe! Zmodyfikowany plik został zapisany do: {tex_out_file}")
if __name__ == "__main__":
main()