Skip to content

Commit

Permalink
feat, docs: enable custom markdown rendering to allow metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
iisakkirotko committed Mar 21, 2024
1 parent 0c33e33 commit 4fc73a1
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 6 deletions.
22 changes: 16 additions & 6 deletions solara/autorouting.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,9 +184,10 @@ def get_args(f):
else:
return []

if isinstance(route_current.data, Path):
if str(route_current.file).endswith(".md") or isinstance(route_current.data, Path):
path = cast(Path, route_current.data)
if path.suffix == ".md":
component = route_current.component or solara.Markdown
with solara.HBox() as navigation:
if routes_siblings_index > 0:
prev = routes_siblings[routes_siblings_index - 1]
Expand All @@ -206,9 +207,11 @@ def get_args(f):
solara.Button(
icon_name="mdi-pencil", icon=True, href=url, target="_blank", style={"position": "absolute", "top": "0px", "right": "0px"}
)
solara.Markdown(path.read_text(), unsafe_solara_execute=True)
# solara.Markdown(path.read_text(), unsafe_solara_execute=True)
component(path.read_text(), unsafe_solara_execute=True)
else:
content = solara.Markdown(path.read_text(), unsafe_solara_execute=True)
# content = solara.Markdown(path.read_text(), unsafe_solara_execute=True)
content = component(path.read_text(), unsafe_solara_execute=True)

main = solara.Div(
classes=["solara-autorouter-content"],
Expand Down Expand Up @@ -312,6 +315,11 @@ def get_page(module: ModuleType, required=True):
return page


def get_markdown_renderer(module: ModuleType):
markdown_renderer = getattr(module, "MarkdownRenderer", None)
return markdown_renderer


def get_renderable(module: ModuleType, required=False):
var_names = "app Page page".split()
for var_name in var_names:
Expand Down Expand Up @@ -462,7 +470,7 @@ def generate_routes(module: ModuleType) -> List[solara.Route]:
return routes


def generate_routes_directory(path: Path) -> List[solara.Route]:
def generate_routes_directory(path: Path, markdown_renderer=None) -> List[solara.Route]:
"""Generate routes for a directory.
This is a recursive function that will generate routes for all
Expand All @@ -487,6 +495,7 @@ def generate_routes_directory(path: Path) -> List[solara.Route]:
if init.exists():
init_module = source_to_module(init)
layout = getattr(init_module, "Layout", None)
markdown_renderer = get_markdown_renderer(init_module) or markdown_renderer

suffixes = [".py", ".ipynb", ".md"]
for subpath in subpaths:
Expand All @@ -495,13 +504,13 @@ def generate_routes_directory(path: Path) -> List[solara.Route]:
continue
if subpath.stem.startswith("_") or subpath.stem.startswith("."):
continue
route = _generate_route_path(subpath, layout=layout, first=first, has_index=has_index)
route = _generate_route_path(subpath, layout=layout, first=first, has_index=has_index, markdown_renderer=markdown_renderer)
first = False
routes.append(route)
return routes


def _generate_route_path(subpath: Path, layout=None, first=False, has_index=False, initial_namespace={}) -> solara.Route:
def _generate_route_path(subpath: Path, layout=None, first=False, has_index=False, initial_namespace={}, markdown_renderer=None) -> solara.Route:
from .server import reload

name = subpath.stem
Expand All @@ -521,6 +530,7 @@ def _generate_route_path(subpath: Path, layout=None, first=False, has_index=Fals
module_layout = layout if first else None
if subpath.suffix == ".md":
data = subpath
component = markdown_renderer
reload.reloader.watcher.add_file(subpath)
elif subpath.is_dir():
children = generate_routes_directory(subpath)
Expand Down
30 changes: 30 additions & 0 deletions solara/website/components/markdown.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from typing import Dict, List, Union

import yaml

import solara


# We want to separate metadata from the markdown files before rendering them, which solara.Markdown doesn't support
@solara.component
def MarkdownWithMetadata(content: str, unsafe_solara_execute=True):
if "---" in content:
pre_content, raw_metadata, post_content = content.split("---")
metadata: Dict[str, Union[str, List[str]]] = yaml.safe_load(raw_metadata)

if len(pre_content) == 0:
content = post_content
else:
content = pre_content + post_content

if "title" not in metadata.keys():
metadata["title"] = content.split("#")[1].split("\n")[0]

for key, value in metadata.items():
if key == "title":
solara.Title(value)
elif ":" in key:
solara.Meta(property=key, content=value)
else:
solara.Meta(name=key, content=value)
solara.Markdown(content, unsafe_solara_execute=unsafe_solara_execute)

0 comments on commit 4fc73a1

Please sign in to comment.