Spaces:
Running
Running
| import os | |
| import re | |
| from typing import Callable | |
| import gradio as gr | |
| import modelscope_gradio_components as mgr | |
| from .parse_markdown import parse_markdown | |
| with open(os.path.join(os.path.dirname(__file__), "tab-link.js")) as f: | |
| tab_link_js = f.read() | |
| custom_components = { | |
| "tab-link": { | |
| "props": ["tab", "component-tab"], | |
| "js": tab_link_js | |
| } | |
| } | |
| def remove_formatter(markdown_text): | |
| pattern = r"^---[\s\S]*?---" | |
| replaced_text = re.sub(pattern, "", markdown_text) | |
| return replaced_text | |
| def list_demos(dir_path: str, prefix=''): | |
| result = [] | |
| if (not os.path.isdir(dir_path)): | |
| return result | |
| for name in os.listdir(dir_path): | |
| path = os.path.join(dir_path, name) | |
| if os.path.isfile(path): | |
| result.append(prefix + name) | |
| elif os.path.isdir(path): | |
| sub_prefix = prefix + name + '/' | |
| result.extend(list_demos(path, sub_prefix)) | |
| return result | |
| def get_demo_modules(file_path: str): | |
| import importlib.util | |
| demos = [ | |
| demo for demo in list_demos( | |
| os.path.join(os.path.dirname(file_path), "demos")) | |
| if demo.endswith(".py") | |
| ] | |
| demo_modules = {} | |
| for demo in demos: | |
| demo_name = demo.split(".")[0] | |
| spec = importlib.util.spec_from_file_location( | |
| "demo", os.path.join(os.path.dirname(file_path), "demos", demo)) | |
| module = importlib.util.module_from_spec(spec) | |
| spec.loader.exec_module(module) | |
| demo_modules[demo_name] = module | |
| return demo_modules | |
| class Docs: | |
| def __init__(self, file_path: str, markdown_files: list = None): | |
| self.file_path = file_path | |
| self.demo_modules = get_demo_modules(file_path) | |
| # default current directory | |
| self.markdown_files = markdown_files if markdown_files else [ | |
| file_name for file_name in os.listdir(os.path.dirname(file_path)) | |
| if file_name.endswith(".md") | |
| ] | |
| self.tabs = None | |
| def read_file(self, relative_path: str): | |
| with open(os.path.join(os.path.dirname(self.file_path), relative_path), | |
| "r") as f: | |
| return f.read() | |
| def render_demo(self, demo_name, prefix='', suffix=''): | |
| content = self.read_file(f"./demos/{demo_name}.py") | |
| module = self.demo_modules[demo_name] | |
| with gr.Accordion("Show Demo", open=False): | |
| with gr.Row(): | |
| with gr.Column(): | |
| mgr.Markdown(f""" | |
| {prefix} | |
| ````python | |
| {content} | |
| ```` | |
| {suffix} | |
| """, | |
| header_links=True, | |
| custom_components=custom_components) | |
| with gr.Column(): | |
| module.demo.render() | |
| def render_markdown(self, | |
| markdown_file, | |
| on_tab_link_click: Callable = None, | |
| components_tabs=None): | |
| items = parse_markdown(remove_formatter(self.read_file(markdown_file)), | |
| read_file=self.read_file) | |
| for item in items: | |
| if item["type"] == "text": | |
| md = mgr.Markdown(item["value"], | |
| header_links=True, | |
| custom_components=custom_components) | |
| # 过滤 | |
| deps = [dep for dep in [components_tabs, self.tabs] if dep] | |
| if len(deps) > 0: | |
| md.custom(fn=on_tab_link_click, outputs=deps) | |
| elif item["type"] == "demo": | |
| self.render_demo(item["name"], | |
| prefix=item["prefix"], | |
| suffix=item["suffix"]) | |
| def render(self, components_tabs=None): | |
| def tab_link_click(data: gr.EventData): | |
| tab: str = data._data["value"].get("tab", '') | |
| component_tab: str = data._data["value"].get("component_tab", '') | |
| if tab and tabs: | |
| return {tabs: gr.update(selected=tab)} | |
| elif components_tabs and component_tab: | |
| return {components_tabs: gr.update(selected=component_tab)} | |
| with gr.Blocks() as demo: | |
| if len(self.markdown_files) > 1: | |
| with gr.Tabs() as tabs: | |
| self.tabs = tabs | |
| for markdown_file in self.markdown_files: | |
| tab_name = ".".join(markdown_file.split(".")[:-1]) | |
| with gr.TabItem(tab_name, id=tab_name): | |
| self.render_markdown( | |
| markdown_file, | |
| on_tab_link_click=tab_link_click, | |
| components_tabs=components_tabs) | |
| else: | |
| self.render_markdown(self.markdown_files[0], | |
| on_tab_link_click=tab_link_click, | |
| components_tabs=components_tabs) | |
| return demo | |