u: add py/struct.py py/ref.py ->m.pdf
This commit is contained in:
parent
3d5d5fc262
commit
2992f20284
22
main.tex
22
main.tex
@ -632,7 +632,7 @@ System oceniania opracowany w oparciu o:
|
|||||||
%----------------------
|
%----------------------
|
||||||
% G. INFORMACJA O OCENIE KOŃCOWEJ
|
% G. INFORMACJA O OCENIE KOŃCOWEJ
|
||||||
%----------------------
|
%----------------------
|
||||||
\item Ocena końcowa
|
\paragraf{Ocena końcowa}
|
||||||
\begin{longenum}
|
\begin{longenum}
|
||||||
\item Ocena końcowa w~danym roku szkolnym jest równoważna z~oceną roczną z~danego przedmiotu
|
\item Ocena końcowa w~danym roku szkolnym jest równoważna z~oceną roczną z~danego przedmiotu
|
||||||
(z~uwzględnieniem ewentualnej oceny śródrocznej), przy czym decydujące znaczenie mają:
|
(z~uwzględnieniem ewentualnej oceny śródrocznej), przy czym decydujące znaczenie mają:
|
||||||
@ -1643,12 +1643,12 @@ i~technikum z~dnia 28 czerwca 2024~r., opracowana przez Ministerstwo Edukacji i~
|
|||||||
\subsection{Klasyfikacja śródroczna (okresowa)}
|
\subsection{Klasyfikacja śródroczna (okresowa)}
|
||||||
\label{subsec:klasyfikacja-srodroczna}
|
\label{subsec:klasyfikacja-srodroczna}
|
||||||
|
|
||||||
\paragraph{Klasyfikacja środroczna}
|
\paragraf{Klasyfikacja środroczna}
|
||||||
\begin{longenum}
|
\begin{longenum}
|
||||||
|
|
||||||
\item \label{itm:srodroczna-zasady-ogolne} Zasady ogólne
|
\item Zasady ogólne
|
||||||
\begin{longenum}
|
\begin{longenum}
|
||||||
\item Klasyfikacja śródroczna (okresowa) przeprowadzana jest jednorazowo w ciągu roku szkolnego.
|
\item Klasyfikacja śródroczna przeprowadzana jest jednorazowo w ciągu roku szkolnego.
|
||||||
\item Obejmuje ona podsumowanie osiągnięć edukacyjnych ucznia w okresie od początku roku szkolnego do końca pierwszego semestru.
|
\item Obejmuje ona podsumowanie osiągnięć edukacyjnych ucznia w okresie od początku roku szkolnego do końca pierwszego semestru.
|
||||||
\item W jej ramach ustala się:
|
\item W jej ramach ustala się:
|
||||||
\begin{longenum}
|
\begin{longenum}
|
||||||
@ -1658,16 +1658,16 @@ i~technikum z~dnia 28 czerwca 2024~r., opracowana przez Ministerstwo Edukacji i~
|
|||||||
\item Klasyfikacja stanowi podstawę do monitorowania postępów ucznia oraz planowania dalszej pracy pedagogicznej.
|
\item Klasyfikacja stanowi podstawę do monitorowania postępów ucznia oraz planowania dalszej pracy pedagogicznej.
|
||||||
\end{longenum}
|
\end{longenum}
|
||||||
|
|
||||||
\item \label{itm:srodroczna-terminy} Terminy klasyfikacyjne:
|
\item Terminy klasyfikacyjne:
|
||||||
\begin{longenum}
|
\begin{longenum}
|
||||||
\item Terminy ustala dyrektor szkoły.
|
\item Termin posiedzenia środrocznej rady klasyfikacyjnej ustala dyrektor szkoły zgodnie z~zasadami określonymi w~[\ref{itm:po-klasyf-dyrektor-okresla-terminy}].
|
||||||
\item Informację o~nieklasyfikowaniu lub przewidywanych niedostatetycznych ocenach śródrocznych nauczyciele przekazują uczniom w~następujących terminach:
|
\item Informację przewidywanych ocenach śródrocznych nauczyciele przekazują uczniom w~następujących terminach:
|
||||||
\begin{longenum}
|
\begin{longenum}
|
||||||
\item W~przypadku zagrożenia oceną niedostateczną — \emph{co najmniej 30~dni} przed terminem tego posiedzenia, zgodnie z zasadami określonymi w [\ref{itm:po-klasyf-informacja-o-zagrozeniu}].
|
\item W~przypadku zagrożenia nieklasyfikacją lub oceną niedostateczną — \emph{co najmniej 30~dni} przed terminem tego posiedzenia, zgodnie z zasadami określonymi w [\ref{itm:po-klasyf-informacja-o-zagrozeniu}].
|
||||||
\end{longenum}
|
\end{longenum}
|
||||||
\end{longenum}
|
\end{longenum}
|
||||||
|
|
||||||
\item \label{itm:srodroczna-podstawa-punktowa} Podstawa punktowa i~zasady ustalania ocen śródrocznych z~zajęć edukacyjnych:
|
\item Podstawa punktowa i~zasady ustalania ocen śródrocznych z~zajęć edukacyjnych:
|
||||||
\begin{longenum}
|
\begin{longenum}
|
||||||
\item Śródroczna ocena klasyfikacyjna z~danego przedmiotu opiera się na liczbie punktów uzyskanych w~pierwszym okresie roku szkolnego, z~uwzględnieniem różnych form sprawdzania wiedzy.
|
\item Śródroczna ocena klasyfikacyjna z~danego przedmiotu opiera się na liczbie punktów uzyskanych w~pierwszym okresie roku szkolnego, z~uwzględnieniem różnych form sprawdzania wiedzy.
|
||||||
\item Ostateczna ocena śródroczna wyliczana jest automatycznie w~programie~Librus jako średnia ważona, przy czym uwzględnia się:
|
\item Ostateczna ocena śródroczna wyliczana jest automatycznie w~programie~Librus jako średnia ważona, przy czym uwzględnia się:
|
||||||
@ -1678,12 +1678,12 @@ i~technikum z~dnia 28 czerwca 2024~r., opracowana przez Ministerstwo Edukacji i~
|
|||||||
\end{longenum}
|
\end{longenum}
|
||||||
\end{longenum}
|
\end{longenum}
|
||||||
|
|
||||||
\item \label{itm:srodroczna-ocena-zachowania} Ocena klasyfikacyjna zachowania:
|
\item Ocena klasyfikacyjna zachowania:
|
||||||
\begin{longenum}
|
\begin{longenum}
|
||||||
\item Śródroczną ocenę klasyfikacyjną zachowania wystawia wychowawca klasy po zasięgnięciu opinii nauczycieli, uczniów oraz opinii samego ocenianego ucznia, zgodnie z punktowymi zasadami oceny zachowania określonymi w Wewnątrzszkolnym Ocenianiu (WO), opisanymi w [\ref{itm:po-klasyf-wychowawca-ocena-zachowania}].
|
\item Śródroczną ocenę klasyfikacyjną zachowania wystawia wychowawca klasy po zasięgnięciu opinii nauczycieli, uczniów oraz opinii samego ocenianego ucznia, zgodnie z punktowymi zasadami oceny zachowania określonymi w Wewnątrzszkolnym Ocenianiu (WO), opisanymi w [\ref{itm:po-klasyf-wychowawca-ocena-zachowania}].
|
||||||
\end{longenum}
|
\end{longenum}
|
||||||
|
|
||||||
\item \label{itm:srodroczna-nieklasyfikowanie} Nieklasyfikowanie śródroczne:
|
\item Nieklasyfikowanie śródroczne:
|
||||||
\begin{longenum}
|
\begin{longenum}
|
||||||
\item Warunki nieklasyfikowania ucznia w klasyfikacji śródrocznej są określone w [\ref{itm:po-klasyf-warunki-klasyfikowalnosci}].
|
\item Warunki nieklasyfikowania ucznia w klasyfikacji śródrocznej są określone w [\ref{itm:po-klasyf-warunki-klasyfikowalnosci}].
|
||||||
\item W przypadku nieklasyfikacji, nauczyciel zobowiązany jest określić ramy i tryb, w jakim uczeń może nadrobić zaległości w drugim półroczu:
|
\item W przypadku nieklasyfikacji, nauczyciel zobowiązany jest określić ramy i tryb, w jakim uczeń może nadrobić zaległości w drugim półroczu:
|
||||||
|
2
py/opis.txt
Normal file
2
py/opis.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
1. struct.py generuje ../main-struct.json
|
||||||
|
2. ref.py zamienia [1] na \S1 ust.1 pkt. 1
|
110
py/ref.py
Normal file
110
py/ref.py
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
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()
|
||||||
|
|
265
py/struct.py
Normal file
265
py/struct.py
Normal file
@ -0,0 +1,265 @@
|
|||||||
|
import re
|
||||||
|
import json
|
||||||
|
|
||||||
|
def process_labels_and_create_links(in_file="../main.tex", out_file="../main-struct.json"):
|
||||||
|
"""
|
||||||
|
Przetwarza plik TeX, usuwa komentarze/puste linie i buduje drzewo paragrafów i list z 9 poziomami:
|
||||||
|
- par (poziom 0, w numeracji: '\\S1')
|
||||||
|
- ust (głębokość listy=1)
|
||||||
|
- pkt (głębokość listy=2)
|
||||||
|
- ppkt (głębokość listy=3)
|
||||||
|
- lit (głębokość listy=4)
|
||||||
|
- plit (głębokość listy=5)
|
||||||
|
- tir (głębokość listy=6)
|
||||||
|
- lev7 (głębokość listy=7)
|
||||||
|
- lev8 (głębokość listy=8)
|
||||||
|
Jeśli głębokość listy > 8 – ostrzeżenie i pominięcie \\item.
|
||||||
|
|
||||||
|
Zapisuje wynik w pliku JSON z polami:
|
||||||
|
type, numbering, label, text, children.
|
||||||
|
|
||||||
|
- type: "par" / "ust" / "pkt" / "ppkt" / "lit" / "plit" / "tir" / "lev7" / "lev8"
|
||||||
|
- numbering: np. '\\S1 ust. 2 pkt. 1 ppkt. 1 lit. a ...'
|
||||||
|
- label: jeśli w tej samej linii występuje \\label{itm:...}, to tu jest ten fragment, w p.p. ""
|
||||||
|
- text: linia z \\item
|
||||||
|
- children: (lista obiektów zagnieżdżonych)
|
||||||
|
"""
|
||||||
|
|
||||||
|
with open(in_file, 'r', encoding='utf-8') as file:
|
||||||
|
content = file.readlines()
|
||||||
|
|
||||||
|
# -- Usunięcie komentarzy i linii pustych --
|
||||||
|
cleaned_content = []
|
||||||
|
for line in content:
|
||||||
|
# usuń wszystko po '%', jeśli nie poprzedza go backslash
|
||||||
|
line = re.sub(r'(?<!\\)%.*$', '', line).strip()
|
||||||
|
if line:
|
||||||
|
cleaned_content.append(line)
|
||||||
|
|
||||||
|
# -- Liczniki poziomów --
|
||||||
|
counters = {
|
||||||
|
"par": 0, # paragraf (\S)
|
||||||
|
"ust": 0, # 1-szy poziom list
|
||||||
|
"pkt": 0, # 2-gi
|
||||||
|
"ppkt": 0, # 3-ci
|
||||||
|
"lit": 0, # 4-ty
|
||||||
|
"plit": 0, # 5-ty
|
||||||
|
"tir": 0, # 6-ty
|
||||||
|
"lev7": 0, # 7-my
|
||||||
|
"lev8": 0 # 8-my
|
||||||
|
}
|
||||||
|
|
||||||
|
MAX_LIST_DEPTH = 8 # maksymalna głębokość zagnieżdżenia list
|
||||||
|
label_tree = [] # główna struktura do zapisu
|
||||||
|
current_env_stack = [] # stos środowisk list
|
||||||
|
errors = []
|
||||||
|
|
||||||
|
level_order = ["par","ust","pkt","ppkt","lit","plit","tir","lev7","lev8"]
|
||||||
|
|
||||||
|
def reset_counters(from_level):
|
||||||
|
"""
|
||||||
|
Zeruje liczniki dla poziomów "niższych" (w level_order) niż from_level.
|
||||||
|
Jeśli from_level=='pkt', zerujemy ppkt, lit, plit, tir, lev7, lev8.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
idx = level_order.index(from_level)
|
||||||
|
except ValueError:
|
||||||
|
return
|
||||||
|
for lv in level_order[idx+1:]:
|
||||||
|
counters[lv] = 0
|
||||||
|
|
||||||
|
def get_current_numbering():
|
||||||
|
"""
|
||||||
|
Zwraca łańcuch numerujący, np:
|
||||||
|
'\\S1 ust. 2 pkt. 3 ppkt. 1 lit. a plit. a) tir. 1 lev7. 2 lev8. 1'
|
||||||
|
z uwzględnieniem tych liczników, które są > 0.
|
||||||
|
"""
|
||||||
|
parts = []
|
||||||
|
|
||||||
|
# par => \S + numer
|
||||||
|
if counters["par"] > 0:
|
||||||
|
parts.append(f"\\S{counters['par']}")
|
||||||
|
|
||||||
|
# ust => ust. X
|
||||||
|
if counters["ust"] > 0:
|
||||||
|
parts.append(f"ust. {counters['ust']}")
|
||||||
|
|
||||||
|
# pkt => pkt. X
|
||||||
|
if counters["pkt"] > 0:
|
||||||
|
parts.append(f"pkt. {counters['pkt']}")
|
||||||
|
|
||||||
|
# ppkt => ppkt. X
|
||||||
|
if counters["ppkt"] > 0:
|
||||||
|
parts.append(f"ppkt. {counters['ppkt']}")
|
||||||
|
|
||||||
|
# lit => lit. a, b, c...
|
||||||
|
if counters["lit"] > 0:
|
||||||
|
letter = chr(96 + counters["lit"]) # 1->a, 2->b, etc.
|
||||||
|
parts.append(f"lit. {letter}")
|
||||||
|
|
||||||
|
# plit => plit. a)
|
||||||
|
if counters["plit"] > 0:
|
||||||
|
letter = chr(96 + counters["plit"])
|
||||||
|
parts.append(f"plit. {letter})")
|
||||||
|
|
||||||
|
# tir => tir. X
|
||||||
|
if counters["tir"] > 0:
|
||||||
|
parts.append(f"tir. {counters['tir']}")
|
||||||
|
|
||||||
|
# lev7 => lev7. X
|
||||||
|
if counters["lev7"] > 0:
|
||||||
|
parts.append(f"lev7. {counters['lev7']}")
|
||||||
|
|
||||||
|
# lev8 => lev8. X
|
||||||
|
if counters["lev8"] > 0:
|
||||||
|
parts.append(f"lev8. {counters['lev8']}")
|
||||||
|
|
||||||
|
# scal całość w jeden łańcuch, oddzielając spacjami
|
||||||
|
return " ".join(parts)
|
||||||
|
|
||||||
|
def get_current_parent():
|
||||||
|
"""
|
||||||
|
Zwraca "bieżący" obiekt-rodzic w label_tree, do którego
|
||||||
|
dołączymy kolejny element (children).
|
||||||
|
"""
|
||||||
|
if not label_tree:
|
||||||
|
return None
|
||||||
|
parent = label_tree[-1]
|
||||||
|
# Głębokość = ile razy mamy 'list' w current_env_stack
|
||||||
|
depth = sum(1 for env in current_env_stack if env=="list")
|
||||||
|
|
||||||
|
# 'par' jest poziomem zerowym. Dla depth=1 => wchodzimy do children paragrafu itd.
|
||||||
|
for _ in range(depth-1):
|
||||||
|
if not parent["children"]:
|
||||||
|
break
|
||||||
|
parent = parent["children"][-1]
|
||||||
|
return parent
|
||||||
|
|
||||||
|
# Regexy do wykrywania \begin{longenum} itp.
|
||||||
|
begin_enum_regex = re.compile(r'\\begin\{(long[a-z0-9]*enum|customenum)\}')
|
||||||
|
end_enum_regex = re.compile(r'\\end\{(long[a-z0-9]*enum|customenum)\}')
|
||||||
|
|
||||||
|
fixed_content = []
|
||||||
|
|
||||||
|
for line_number, line in enumerate(cleaned_content, start=1):
|
||||||
|
|
||||||
|
# --- wykrywanie paragrafu \paragraf{...} ---
|
||||||
|
paragraf_match = re.search(r'\\paragraf\{([^}]+)\}', line)
|
||||||
|
if paragraf_match:
|
||||||
|
counters["par"] += 1
|
||||||
|
reset_counters("par")
|
||||||
|
par_title = paragraf_match.group(1).strip()
|
||||||
|
|
||||||
|
label_tree.append({
|
||||||
|
"type": "par",
|
||||||
|
"numbering": get_current_numbering(),
|
||||||
|
"label": "",
|
||||||
|
"text": line.strip(),
|
||||||
|
"children": []
|
||||||
|
})
|
||||||
|
fixed_content.append(line)
|
||||||
|
continue
|
||||||
|
|
||||||
|
# --- wykrywanie \begin{...enum} ---
|
||||||
|
if begin_enum_regex.search(line):
|
||||||
|
current_env_stack.append("list")
|
||||||
|
fixed_content.append(line)
|
||||||
|
continue
|
||||||
|
|
||||||
|
# --- wykrywanie \end{...enum} ---
|
||||||
|
if end_enum_regex.search(line):
|
||||||
|
if "list" in current_env_stack:
|
||||||
|
# Usunięcie ze stosu "list" od prawej
|
||||||
|
stack_rev = current_env_stack[::-1]
|
||||||
|
stack_rev.remove("list")
|
||||||
|
current_env_stack = stack_rev[::-1]
|
||||||
|
fixed_content.append(line)
|
||||||
|
continue
|
||||||
|
|
||||||
|
# --- wykrywanie \item ---
|
||||||
|
if r'\item' in line:
|
||||||
|
depth = sum(env=="list" for env in current_env_stack)
|
||||||
|
if depth==0:
|
||||||
|
errors.append(f"[Linia {line_number}] \\item poza listą. Ignoruję.")
|
||||||
|
else:
|
||||||
|
if depth==1:
|
||||||
|
counters["ust"] += 1
|
||||||
|
reset_counters("ust")
|
||||||
|
level_type = "ust"
|
||||||
|
elif depth==2:
|
||||||
|
counters["pkt"] += 1
|
||||||
|
reset_counters("pkt")
|
||||||
|
level_type = "pkt"
|
||||||
|
elif depth==3:
|
||||||
|
counters["ppkt"] += 1
|
||||||
|
reset_counters("ppkt")
|
||||||
|
level_type = "ppkt"
|
||||||
|
elif depth==4:
|
||||||
|
counters["lit"] += 1
|
||||||
|
reset_counters("lit")
|
||||||
|
level_type = "lit"
|
||||||
|
elif depth==5:
|
||||||
|
counters["plit"] += 1
|
||||||
|
reset_counters("plit")
|
||||||
|
level_type = "plit"
|
||||||
|
elif depth==6:
|
||||||
|
counters["tir"] += 1
|
||||||
|
reset_counters("tir")
|
||||||
|
level_type = "tir"
|
||||||
|
elif depth==7:
|
||||||
|
counters["lev7"] += 1
|
||||||
|
reset_counters("lev7")
|
||||||
|
level_type = "lev7"
|
||||||
|
elif depth==8:
|
||||||
|
counters["lev8"] += 1
|
||||||
|
reset_counters("lev8")
|
||||||
|
level_type = "lev8"
|
||||||
|
else:
|
||||||
|
errors.append(f"[Linia {line_number}] Zbyt głębokie zagnieżdżenie (>8). Pomijam \\item.")
|
||||||
|
fixed_content.append(line)
|
||||||
|
continue
|
||||||
|
|
||||||
|
label_match = re.search(r'\\label\{(itm:[^}]+)\}', line)
|
||||||
|
if label_match:
|
||||||
|
label_str = label_match.group(1)
|
||||||
|
else:
|
||||||
|
label_str = ""
|
||||||
|
|
||||||
|
parent = get_current_parent()
|
||||||
|
if parent is not None:
|
||||||
|
new_item = {
|
||||||
|
"type": level_type,
|
||||||
|
"numbering": get_current_numbering(),
|
||||||
|
"label": label_str,
|
||||||
|
"text": line.strip(),
|
||||||
|
"children": []
|
||||||
|
}
|
||||||
|
parent["children"].append(new_item)
|
||||||
|
|
||||||
|
fixed_content.append(line)
|
||||||
|
continue
|
||||||
|
|
||||||
|
fixed_content.append(line)
|
||||||
|
|
||||||
|
# Zapisz drzewo w pliku JSON
|
||||||
|
with open(out_file, "w", encoding="utf-8") as f:
|
||||||
|
json.dump(label_tree, f, ensure_ascii=False, indent=2)
|
||||||
|
|
||||||
|
if errors:
|
||||||
|
print("== OSTRZEŻENIA / KOMUNIKATY ==")
|
||||||
|
for err in errors:
|
||||||
|
print("•", err)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import sys
|
||||||
|
args = sys.argv[1:]
|
||||||
|
if len(args)==0:
|
||||||
|
process_labels_and_create_links()
|
||||||
|
elif len(args)==1:
|
||||||
|
process_labels_and_create_links(in_file=args[0])
|
||||||
|
elif len(args)==2:
|
||||||
|
process_labels_and_create_links(in_file=args[0], out_file=args[1])
|
||||||
|
else:
|
||||||
|
print("Użycie: python script.py [plik_wejściowy] [plik_wyjściowy]")
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user