""" * Each folder should have an entry MD file to describe its content and functions * A loop over all valid first-level folders Navigation panel: Src [1st level] Python Notes [2nd level] ... projects ... C Notes ... projects ... Weblog [1st level] Folder 1 [2nd level] Devlog [1st level] """ import re import os import sys import shutil from datetime import datetime from typing import Union, Optional, Tuple sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../', 'src/PyThon'))) import Docy # Assuming this module provides extract_python_functions and extract_c_functions source_dirs = { 'WebLog' : ['doc/WebLog'], 'Devlog' : ['doc/Devlog'], 'Projects' : ['Projects'], 'PyThon' : ['src/PyThon'], 'C' : ['src/C'], 'C++' : ['src/CPP'], 'CUDA' : ['src/CUDA'], } lang_colors = { 'Devlog' : '#8B008B', 'WebLog' : '#076E75', 'Projects' : "#F1EE20", 'PyThon' : '#3572A5', 'C' : '#555555', 'C++' : '#F34B7D', 'CUDA' : "#318F8A", } output_base_dir = 'docs' def processor(lang:str, content_html:str, file_path:Union[str, os.PathLike], base_name:Union[str, os.PathLike], processed_files:list, label_to_file:dict) -> Tuple[list, dict]: """ Process the given file and generate the corresponding HTML output. Designed to be universal by receiving the content as a string. 1. Extracts labels from the content. 2. Generates the HTML path based on the language and file structure. 3. Creates the processed file entry with content, labels, and paths. 4. Updates the label_to_file mapping with the new file path. Args: lang (str): The programming language of the file. content_html (str): The HTML content to be processed. file_path (Union[str, os.PathLike]): The path to the source file. base_name (Union[str, os.PathLike]): The base name of the file. processed_files (list): List to store processed file information. label_to_file (dict): Dictionary mapping labels to file paths. Returns: Tuple containing the updated processed_files list and label_to_file dictionary. """ rel_path = os.path.relpath(file_path, start=lang) if ("README.md" in file_path): html_path = os.path.join(output_base_dir, lang, os.path.split(rel_path)[0] + '.html') base_name = os.path.split(os.path.split(rel_path)[0])[1] elif(".md" in file_path): html_path = os.path.join(output_base_dir, lang, os.path.splitext(rel_path)[0] + '.html') base_name = os.path.split(os.path.split(rel_path)[0])[1] else: content_html = '\n'.join(content_html) if content_html else '

No functions found.

' html_path = os.path.join(output_base_dir, lang, os.path.splitext(rel_path)[0] + '.html') content_html, labels = Docy.process_html_for_labels(content_html) html_path = os.path.normpath(html_path) os.makedirs(os.path.dirname(html_path), exist_ok=True) processed_files.append({ 'content_html': content_html, 'lang': lang, 'source_path': file_path, 'html_path': html_path, 'name': base_name, 'type': 'source', #TODO 'labels': labels }) for label in labels: if label in label_to_file: print(f"Warning: duplicate label '{label}' in {html_path} and {label_to_file[label]}") label_to_file[label] = html_path return processed_files, label_to_file def process_decider(lang:str, file_path:Union[str, os.PathLike],base_name:Union[str, os.PathLike], file_extension:str, processed_files:list, label_to_file:dict, output_base_dir:Union[str, os.PathLike]) -> Tuple[list, dict]: """ Decide how to process the file based on its extension. Should be updated based on language and file type. 1. For C files, extract functions and generate HTML. 2. For Python files, extract objects and generate HTML. 3. For Markdown files, convert to HTML. TODO: - Add support for C++ files. - Add support for CUDA files. - Add support for other file types if needed. Args: lang (str): The programming language of the file. file_path (Union[str, os.PathLike]): The path to the source file. base_name (Union[str, os.PathLike]): The base name of the file. file_extension (str): The file extension to determine processing type. processed_files (list): List to store processed file information. label_to_file (dict): Dictionary mapping labels to file paths. output_base_dir (Union[str, os.PathLike]): The base directory for output files. Returns: Tuple containing the updated processed_files list and label_to_file dictionary. """ if file_extension == ".c": functions = Docy.extract_c_functions(file_path) content = [Docy.generate_c_function_html(func) for func in functions] return processor(lang, content,file_path, base_name, processed_files, label_to_file) elif file_extension == ".cpp": functions = Docy.extract_cpp_objects(file_path) content = [Docy.generate_html(func) for func in functions] return processor(lang, content,file_path, base_name, processed_files, label_to_file) # elif file_extension == ".cu": # raise NotImplementedError("CUDA files (.cu) processing is not implemented yet.") # functions = Docy.extract_cuda_functions(file_path) # content = [Docy.generate_cuda_function_html(func) for func in functions] # return processor(lang, content,file_path, base_name, processed_files, label_to_file) # elif file_extension == ".h": # raise NotImplementedError("C header files (.h) processing is not implemented yet.") # functions = Docy.extract_c_functions(file_path) # content = [Docy.generate_c_function_html(func) for func in functions] # return processor(lang, content,file_path, base_name, processed_files, label_to_file) # elif file_extension == ".hpp": # raise NotImplementedError("C++ header files (.hpp) processing is not implemented yet.") # functions = Docy.extract_cpp_functions(file_path) # content = [Docy.generate_cpp_function_html(func) for func in functions] # return processor(lang, content,file_path, base_name, processed_files, label_to_file) elif file_extension == ".py" and not file_path.endswith("__init__.py"): functions = Docy.extract_python_objects(file_path) content = [Docy.generate_html(func) for func in functions] return processor(lang, content,file_path, base_name, processed_files, label_to_file) elif file_extension == ".md": content = Docy.markdown2HTML(file_path) return processor(lang, content,file_path, base_name, processed_files, label_to_file) def build_tree(files, source_dir): """Build a nested dictionary for navigation structure.""" tree = {} for file in files: rel_path = os.path.relpath(file['source_path'], source_dir) parts = rel_path.split(os.sep) current = tree for part in parts[:-1]: if part not in current: current[part] = {} current = current[part] current[parts[-1]] = file['html_path'] return tree def generate_tree_html(tree, current_file_path, current_path_parts=None, indent_level=1): """Generate HTML for navigation tree with collapsible sections and indentation.""" if current_path_parts is None: current_path_parts = [] html = [f'{"\t"*indent_level}') return '\n'.join(html) def create_nav_menu(processed_files, current_file_path, indent_level=3): """Create navigation menu with language and devlog sections, applying distinct colors.""" current_file = next((f for f in processed_files if f['html_path'] == current_file_path), None) languages = {} for file in processed_files: lang = file['lang'] if lang not in languages: languages[lang] = [] languages[lang].append(file) nav_html = [f'']) return '\n'.join(nav_html) def GenerateMainPage(processed_files): """Generate index.html with all sections.""" _TODOs = [] _FIXMEs = [] _HACKs = [] _XXXs = [] index_content = ['

Project Documentation

', '
'] index_content.append(f'

All Files

') index_content.append('
') index_content_html = '' index_content_html += Docy.create_Blue_tags('TODO', _TODOs) index_content_html += Docy.create_Blue_tags('FIXME',_FIXMEs) index_content_html += Docy.create_Blue_tags('HACK', _HACKs) index_content_html += Docy.create_Blue_tags('XXX', _XXXs) index_content_html += '\n'.join(index_content) with open('doc/template.html', 'r') as f: template = f.read() file = {} file['html_path'] = os.path.join(output_base_dir, 'index.html') output = template.replace('', 'Project Documentation') output = output.replace('', Docy.css_styles(file)) output = output.replace('', create_nav_menu(processed_files, file['html_path'])) output = output.replace('', index_content_html) output = output.replace('', datetime.now().strftime('%Y-%m-%d %H:%M:%S')) output = output.replace('', 'https://github.com/YassinRiyazi/Main') with open(os.path.join(output_base_dir, 'index.html'), 'w') as f: f.write(output) def main(source_dirs): if os.path.isdir(output_base_dir): shutil.rmtree(output_base_dir) os.makedirs(output_base_dir, exist_ok=True) shutil.copytree(os.path.join('doc', 'styles'), os.path.join(output_base_dir, 'styles'), dirs_exist_ok=True) # Process source files processed_files = [] label_to_file = {} file_name_to_html_path = {} for lang, lists in source_dirs.items(): for dir_path in lists: if os.path.exists(dir_path): for root, _, files in os.walk(dir_path): for file in files: filename, file_extension = os.path.splitext(file) file_path = os.path.join(root, file) process_decider(lang, file_path, filename, file_extension, processed_files, label_to_file, output_base_dir) # file_name_to_html_path = Docy.fileNameExtractor(processed_files, source_dirs) file_name_to_html_path = Docy.fileNameExtractor_Langless(processed_files, source_dirs) # Generate HTML for all files with file name hyperlinks _tempWebAdress = "https://raw.githubusercontent.com/YassinRiyazi/Main/refs/heads/main/" for file in processed_files: with open('doc/template.html', 'r') as f: template = f.read() if file['type'] == 'source': title = f"{file['name']} " elif file['type'] == 'notes': title = f"{file['lang']} Notes" elif file['type'] == 'Devlog': title = f"" elif file['type'] == 'WebLog': title = f"" # content_html = Docy.replace_file_names_in_html(file['content_html'], file_name_to_html_path.get(file['lang'], {}), file['html_path']) content_html = Docy.replace_file_names_in_html(file['content_html'], file_name_to_html_path, file['html_path']) output = template.replace('', title) output = output.replace('', Docy.css_styles(file)) output = output.replace('', create_nav_menu(processed_files, file['html_path'])) output = output.replace('', content_html)#content_html output = output.replace('', datetime.now().strftime('%Y-%m-%d %H:%M:%S')) output = output.replace('', f'{_tempWebAdress}{file["source_path"]}') with open(file['html_path'], 'w') as f: f.write(output) Docy.process_html_for_labels_replace(processed_files, label_to_file) GenerateMainPage(processed_files) if __name__ == "__main__": main(source_dirs) """ Unified file processing instead having different branch for each file. """