Spaces:
Running
Running
import os | |
import re | |
import gradio as gr | |
import modelscope_studio.components.antd as antd | |
import modelscope_studio.components.base as ms | |
from .env import is_modelscope_studio | |
from .parse_markdown import parse_markdown | |
class Docs: | |
def __init__(self, file_path: str): | |
self.file_path = file_path | |
# default current directory | |
self.markdown_files = [ | |
filename for filename in os.listdir(os.path.dirname(file_path)) | |
if filename.endswith(".md") | |
] | |
self.demo_modules = self._get_demo_modules() | |
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)) | |
def _get_filename(self, filename: str): | |
if is_modelscope_studio: | |
return f"{filename}-zh_CN.md" | |
return f"{filename}.md" | |
def _remove_formatter(self, markdown_text): | |
pattern = r"^ *---[\s\S]*?---" | |
replaced_text = re.sub(pattern, "", markdown_text) | |
return replaced_text | |
def _list_demos(self, 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(self._list_demos(path, sub_prefix)) | |
return result | |
def _get_demo_modules(self): | |
import importlib.util | |
demos = [ | |
demo for demo in self._list_demos( | |
os.path.join(os.path.dirname(self.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(self.file_path), "demos", demo)) | |
module = importlib.util.module_from_spec(spec) | |
spec.loader.exec_module(module) | |
demo_modules[demo_name] = module | |
return demo_modules | |
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='', | |
position="left", | |
collapsible=False, | |
fixed=False, | |
title=''): | |
content = self._read_file(f"./demos/{demo_name}.py") | |
module = self.demo_modules[demo_name] | |
with antd.Card(styles=dict(body=dict(padding=10)), | |
elem_style=dict(margin="8px 0")): | |
if title: | |
with ms.Slot("title"): | |
ms.Text(title) | |
with antd.Row(align="stretch", wrap=True, gutter=[8, 8]): | |
with antd.Col(sm=dict(span=24 if position == "bottom" else 10, | |
order=2 if position == "bottom" else 1), | |
xs=dict(span=24, order=2)): | |
def render_code(): | |
with antd.Row(elem_style=dict(height='100%'), | |
gutter=[8, 8]): | |
with antd.Col(sm=0, xs=24): | |
antd.Divider(type="horizontal", | |
variant="dashed", | |
elem_style=dict(width='100%', | |
margin='8px 0 0')) | |
resolved_prefix = prefix + "\n" if prefix else "" | |
resolved_suffix = suffix + "\n" if suffix else "" | |
with antd.Col(sm=23, xs=24): | |
ms.Markdown(f"""{resolved_prefix}```python | |
{content} | |
```{resolved_suffix}""", | |
header_links=True) | |
with antd.Col(sm=1, | |
xs=0, | |
elem_style=dict(height="100%")): | |
with ms.Div(elem_style=dict( | |
display="flex", | |
justifyContent="center", | |
width="100%", | |
height="100%")): | |
antd.Divider(type="vertical", | |
variant="dashed", | |
elem_style=dict(height='100%', | |
margin=0)) | |
if collapsible: | |
with antd.Collapse(): | |
with antd.Collapse.Item(label="Show Code", | |
key="code"): | |
render_code() | |
else: | |
render_code() | |
with antd.Col( | |
sm=dict(span=24 if position == "bottom" else 14, | |
order=1 if position == "bottom" else 2), | |
xs=dict(span=24, order=1), | |
elem_style=dict( | |
width='100%', | |
transform="translate(0, 0)" if fixed else None)): | |
module.demo.render() | |
def _render_markdown(self, markdown_file): | |
items = parse_markdown(self._remove_formatter( | |
self._read_file(markdown_file)), | |
read_file=self._read_file) | |
for item in items: | |
if item["type"] == "text": | |
ms.Markdown(item["value"], header_links=True) | |
elif item["type"] == "demo": | |
self._render_demo(item["name"], | |
prefix=item["prefix"], | |
suffix=item["suffix"], | |
position=item["position"], | |
collapsible=item["collapsible"], | |
fixed=item["fixed"], | |
title=item["title"]) | |
def get_css(self): | |
css = "" | |
for demo_name in self.demo_modules: | |
module = self.demo_modules[demo_name] | |
if hasattr(module, "css"): | |
css += module.css | |
return css | |
def render(self, module_name: str = None): | |
parsed_filename = self._get_filename( | |
module_name) if module_name else None | |
with gr.Blocks() as demo: | |
self._render_markdown( | |
parsed_filename if parsed_filename else self.markdown_files[0]) | |
return demo | |