import html import os import re import shutil from collections import defaultdict SRC_DIR = "src" DST_DIR = "dst" IMG_DIR = "img" INCLUDE_DIR = "inc" os.makedirs(DST_DIR, exist_ok=True) def copy_file(src, dst): try: shutil.copy(src, dst) except FileNotFoundError: print(f"Warning: {src} not found. Skipping.") def copy_folder(src, dst): try: if os.path.exists(dst): shutil.rmtree(dst) shutil.copytree(src, dst) except Exception as e: print(f"Error copying folder {src} to {dst}: {e}") def read_file(filepath, encoding="utf-8"): try: with open(filepath, "r", encoding=encoding) as file: return file.read() except FileNotFoundError: print(f"Warning: {filepath} not found.") return "" def write_file(filepath, content, encoding="utf-8"): with open(filepath, "w", encoding=encoding) as file: file.write(content) def set_permissions(DST_DIR): for root, dirs, files in os.walk(DST_DIR): for dir_name in dirs: dir_path = os.path.join(root, dir_name) os.chmod(dir_path, 0o755) for file_name in files: file_path = os.path.join(root, file_name) os.chmod(file_path, 0o644) backlink_map = defaultdict(set) def find_internal_links(text, current_file): re.sub(r"{([a-zA-Z0-9_]+)(?:\s+([^}]*))?}", lambda m: backlink_map[m.group(1)].add(current_file), text) def process_internal_links(text): return re.sub( r"{([a-zA-Z0-9_]+)(?:\s+([^}]+))?}", lambda m: f'{m.group(2) if m.group(2) else m.group(1)}', text,) def include_image(image_file): for ext in ["jpg", "png"]: img_path = os.path.join(IMG_DIR, f"{image_file}.{ext}") if os.path.exists(img_path): return f'{image_file}.{ext}' return "" def include_file(file_type, reference): dir_map = {"code": "code", "text": "text"} parts = reference.split(":") filename = parts[0] line_ranges = parts[1:] file_path = os.path.join( INCLUDE_DIR, dir_map[file_type], filename if file_type == "code" else f"{filename}.txt" ) content = read_file(file_path) if not content: return f"
File not found: {filename}==> {file_path}
' content_lines = content.splitlines() selected_lines = [] for line_range in line_ranges: try: if "-" in line_range: start, end = map(int, line_range.split("-")) selected_lines.append("\n".join(content_lines[start - 1:end])) else: line = int(line_range) selected_lines.append(content_lines[line - 1]) except (ValueError, IndexError): selected_lines.append(f"Error processing range: {line_range}") formatted_content = "\n\n[...]\n\n".join(selected_lines) escaped_content = html.escape(formatted_content) return f"
{file_path}
\n{escaped_content}
" def convert_inline_markup(text): text = re.sub( r"`(.*?)`", lambda m: f"{html.escape(m.group(1))}", text ) text = re.sub(r"\*(.*?)\*", r"\1", text) text = re.sub(r"~(.*?)~", r"\1", text) text = re.sub(r"`(.*?)`", r"\1", text) text = re.sub(r"(?)=(?!>)",r"\1",text) return text def handle_list(html_lines, line, in_list): if not in_list: html_lines.append("