Spaces:
Running
Running
File size: 4,961 Bytes
630cbf4 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
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
|