import gradio as gr import os import re import markdown from typing import Dict, Any def create_manual_tab(constant: Dict[str, Any]) -> Dict[str, Any]: # 添加自定义CSS,增大文本大小并添加左侧导航栏样式 custom_css = """ """ # 添加JavaScript代码,用于处理导航点击 custom_js = """ """ # 使用Python的markdown库将Markdown转换为HTML def markdown_to_html(markdown_content, base_path="src/web/manual"): """将Markdown内容转换为HTML,并将图片嵌入为base64编码""" # 处理图片路径,使用base64编码直接嵌入图片 def embed_image(match): alt_text = match.group(1) img_path = match.group(2) # 检查路径是否为外部URL if img_path.startswith(('http://', 'https://')): return f'{alt_text}' # 处理本地图片路径 try: # 去掉开头的/以获取正确的路径 if img_path.startswith('/'): img_path = img_path[1:] # 获取绝对路径 current_dir = os.path.dirname(os.path.abspath(__file__)) project_root = os.path.dirname(os.path.dirname(current_dir)) abs_img_path = os.path.join(project_root, img_path) # 读取图片并转换为base64 import base64 from pathlib import Path image_path = Path(abs_img_path) if image_path.exists(): image_type = image_path.suffix.lstrip('.').lower() if image_type == 'jpg': image_type = 'jpeg' with open(image_path, "rb") as img_file: encoded_string = base64.b64encode(img_file.read()).decode('utf-8') return f'{alt_text}' else: print(f"图片文件不存在: {abs_img_path}") return f'[图片不存在: {img_path}]' except Exception as e: print(f"处理图片时出错: {e}, 路径: {img_path}") return f'[图片加载错误: {img_path}]' # 使用正则表达式处理所有图片标记 pattern = r'!\[(.*?)\]\((.*?)\)' processed_content = re.sub(pattern, embed_image, markdown_content) # 使用Python的markdown库进行转换 html = markdown.markdown( processed_content, extensions=[ 'tables', 'fenced_code', 'codehilite', 'nl2br', 'extra', 'mdx_truly_sane_lists' ], extension_configs={ 'mdx_truly_sane_lists': { 'nested_indent': 2, 'truly_sane': True } } ) return html # 从Markdown内容生成HTML导航栏和处理内容 def generate_toc_and_content(markdown_content): """从Markdown内容生成HTML导航栏和处理内容""" # 提取所有标题 headers = re.findall(r'^(#{1,3})\s+(.+)$', markdown_content, re.MULTILINE) if not headers: return "

目录加载中...

", markdown_content toc_html = "
" # 为Markdown内容中的标题添加ID processed_content = markdown_content for i, (level, title) in enumerate(headers): header_id = f"header-{i}" header_pattern = f"{level} {title}" header_replacement = f"{level} {title}" processed_content = processed_content.replace(header_pattern, header_replacement, 1) # 将处理后的Markdown转换为HTML html_content = markdown_to_html(processed_content) return toc_html, html_content with gr.Tab("Manual"): # 添加自定义CSS和JavaScript gr.HTML(custom_css + custom_js) with gr.Row(): language = gr.Dropdown(choices=['English', 'Chinese'], value='English', label='Language', interactive=True) with gr.Tab("Training"): training_content = load_manual_training(language.value) toc_html, html_content = generate_toc_and_content(training_content) training_md = gr.HTML(f"""
{toc_html}
{html_content}
""") with gr.Tab("Prediction"): prediction_content = load_manual_prediction(language.value) toc_html, html_content = generate_toc_and_content(prediction_content) prediction_md = gr.HTML(f"""
{toc_html}
{html_content}
""") with gr.Tab("Evaluation"): evaluation_content = load_manual_evaluation(language.value) toc_html, html_content = generate_toc_and_content(evaluation_content) evaluation_md = gr.HTML(f"""
{toc_html}
{html_content}
""") with gr.Tab("Download"): download_content = load_manual_download(language.value) toc_html, html_content = generate_toc_and_content(download_content) download_md = gr.HTML(f"""
{toc_html}
{html_content}
""") with gr.Tab("FAQ"): faq_content = load_manual_faq(language.value) toc_html, html_content = generate_toc_and_content(faq_content) faq_md = gr.HTML(f"""
{toc_html}
{html_content}
""") # 正确绑定语言切换事件 language.change( fn=update_manual, inputs=[language], outputs=[training_md, prediction_md, evaluation_md, download_md, faq_md] ) return {"training_md": training_md, "prediction_md": prediction_md, "evaluation_md": evaluation_md, "download_md": download_md, "faq_md": faq_md} def update_manual(language): """更新手册内容""" training_content = load_manual_training(language) prediction_content = load_manual_prediction(language) evaluation_content = load_manual_evaluation(language) download_content = load_manual_download(language) faq_content = load_manual_faq(language) # 使用Python的markdown库将Markdown转换为HTML def markdown_to_html(markdown_content, base_path="src/web/manual"): """将Markdown内容转换为HTML,并将图片嵌入为base64编码""" # 处理图片路径,使用base64编码直接嵌入图片 def embed_image(match): alt_text = match.group(1) img_path = match.group(2) # 检查路径是否为外部URL if img_path.startswith(('http://', 'https://')): return f'{alt_text}' # 处理本地图片路径 try: # 去掉开头的/以获取正确的路径 if img_path.startswith('/'): img_path = img_path[1:] # 获取绝对路径 current_dir = os.path.dirname(os.path.abspath(__file__)) project_root = os.path.dirname(os.path.dirname(current_dir)) abs_img_path = os.path.join(project_root, img_path) # 读取图片并转换为base64 import base64 from pathlib import Path image_path = Path(abs_img_path) if image_path.exists(): image_type = image_path.suffix.lstrip('.').lower() if image_type == 'jpg': image_type = 'jpeg' with open(image_path, "rb") as img_file: encoded_string = base64.b64encode(img_file.read()).decode('utf-8') return f'{alt_text}' else: print(f"图片文件不存在: {abs_img_path}") return f'[图片不存在: {img_path}]' except Exception as e: print(f"处理图片时出错: {e}, 路径: {img_path}") return f'[图片加载错误: {img_path}]' # 使用正则表达式处理所有图片标记 pattern = r'!\[(.*?)\]\((.*?)\)' processed_content = re.sub(pattern, embed_image, markdown_content) # 使用Python的markdown库进行转换 html = markdown.markdown( processed_content, extensions=[ 'tables', 'fenced_code', 'codehilite', 'nl2br', 'extra', 'mdx_truly_sane_lists' ], extension_configs={ 'mdx_truly_sane_lists': { 'nested_indent': 2, 'truly_sane': True } } ) return html # 为每个内容生成导航栏和HTML内容 def generate_toc_and_content(markdown_content): """从Markdown内容生成HTML导航栏和处理内容""" # 提取所有标题 headers = re.findall(r'^(#{1,3})\s+(.+)$', markdown_content, re.MULTILINE) if not headers: return "

目录加载中...

", markdown_content toc_html = "
" # 为Markdown内容中的标题添加ID processed_content = markdown_content for i, (level, title) in enumerate(headers): header_id = f"header-{i}" header_pattern = f"{level} {title}" header_replacement = f"{level} {title}" processed_content = processed_content.replace(header_pattern, header_replacement, 1) # 将处理后的Markdown转换为HTML html_content = markdown_to_html(processed_content) return toc_html, html_content # 生成带导航栏的HTML training_toc, training_html = generate_toc_and_content(training_content) prediction_toc, prediction_html = generate_toc_and_content(prediction_content) evaluation_toc, evaluation_html = generate_toc_and_content(evaluation_content) download_toc, download_html = generate_toc_and_content(download_content) faq_toc, faq_html = generate_toc_and_content(faq_content) training_output = f"""
{training_toc}
{training_html}
""" prediction_output = f"""
{prediction_toc}
{prediction_html}
""" evaluation_output = f"""
{evaluation_toc}
{evaluation_html}
""" download_output = f"""
{download_toc}
{download_html}
""" faq_output = f"""
{faq_toc}
{faq_html}
""" return training_output, prediction_output, evaluation_output, download_output, faq_output def load_manual_training(language): if language == 'Chinese': manual_path = os.path.join("src/web/manual", "TrainingManual_ZH.md") else: manual_path = os.path.join("src/web/manual", "TrainingManual_EN.md") try: with open(manual_path, "r", encoding="utf-8") as f: return f.read() except Exception as e: return f"# Error loading manual\n\n{str(e)}" def load_manual_prediction(language): if language == 'Chinese': manual_path = os.path.join("src/web/manual", "PredictionManual_ZH.md") else: manual_path = os.path.join("src/web/manual", "PredictionManual_EN.md") try: with open(manual_path, "r", encoding="utf-8") as f: return f.read() except Exception as e: return f"# Error loading manual\n\n{str(e)}" def load_manual_evaluation(language): if language == 'Chinese': manual_path = os.path.join("src/web/manual", "EvaluationManual_ZH.md") else: manual_path = os.path.join("src/web/manual", "EvaluationManual_EN.md") try: with open(manual_path, "r", encoding="utf-8") as f: return f.read() except Exception as e: return f"# Error loading manual\n\n{str(e)}" def load_manual_download(language): if language == 'Chinese': manual_path = os.path.join("src/web/manual", "DownloadManual_ZH.md") else: manual_path = os.path.join("src/web/manual", "DownloadManual_EN.md") try: with open(manual_path, "r", encoding="utf-8") as f: return f.read() except Exception as e: return f"# Error loading manual\n\n{str(e)}" def load_manual_faq(language): if language == 'Chinese': manual_path = os.path.join("src/web/manual", "QAManual_ZH.md") else: manual_path = os.path.join("src/web/manual", "QAManual_EN.md") try: with open(manual_path, "r", encoding="utf-8") as f: return f.read() except Exception as e: return f"# FAQ\n\n{str(e)}"