Spaces:
Running
Running
File size: 6,316 Bytes
db32e48 176823e db32e48 176823e db32e48 176823e db32e48 176823e db32e48 176823e db32e48 176823e db32e48 |
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 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
import os
import re
from typing import Callable
import gradio as gr
import modelscope_studio 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") and not demo.startswith("__")
]
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
is_modelscope_studio = os.getenv('MODELSCOPE_ENVIRONMENT') == 'studio'
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 [
filename for filename in os.listdir(os.path.dirname(file_path))
if filename.endswith(".md")
]
if is_modelscope_studio:
self.markdown_files = list(
filter(
lambda x: x.endswith("-zh_CN.md") or
(f"{'.'.join(x.split('.')[:-1])}-zh_CN.md" not in self.
markdown_files), self.markdown_files))
else:
self.markdown_files = list(
filter(lambda x: not x.endswith("-zh_CN.md"),
self.markdown_files))
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,
code_position='left',
prefix='',
suffix=''):
content = self.read_file(f"./demos/{demo_name}.py")
module = self.demo_modules[demo_name]
with gr.Accordion("Show Demo", open=False):
def render_code():
mgr.Markdown(f"""{prefix}
````python
{content}
````
{suffix}""",
header_links=True,
custom_components=custom_components)
if code_position == 'top':
with gr.Row():
with gr.Column():
render_code()
with gr.Row():
if code_position == 'left':
with gr.Column():
render_code()
with gr.Column():
module.demo.render()
if code_position == 'right':
with gr.Column():
render_code()
if code_position == 'bottom':
with gr.Row():
with gr.Column():
render_code()
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,
preview=False)
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"],
code_position=item["code_position"])
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])
tab_name = tab_name.split("-zh_CN")[0]
with gr.TabItem(tab_name, id=tab_name):
self.render_markdown(
markdown_file,
on_tab_link_click=tab_link_click,
components_tabs=components_tabs)
elif (len(self.markdown_files) == 1):
self.render_markdown(self.markdown_files[0],
on_tab_link_click=tab_link_click,
components_tabs=components_tabs)
return demo
|