Coloring's picture
Add FAQ
a1809de
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