"
@Component
def MarkdownText(text: object) -> str:
"""Render preformatted plain text. This component intentionally does not parse Markdown."""
return f'
{escape(str(text)).replace(chr(10), " ")}
'
@Component
def RawHTML(html: str) -> str:
"""Insert trusted HTML without escaping."""
return str(html)
@Component
def Image(
name: str,
alt: str = "",
*,
caption: str | None = None,
width: int | str | None = None,
) -> str:
normalised = PurePosixPath(str(name).replace("\\", "/"))
if normalised.is_absolute() or ".." in normalised.parts:
raise ValueError("Image name must be a relative path inside assets_dir")
asset_name = str(normalised)
width_attr = f' width="{escape(str(width), quote=True)}"' if width is not None else ""
image = (
f''
)
if caption is None:
return image
return f"{image}{escape(caption)}"
@Component
def Link(text: object, href: str, *, external: bool = False) -> str:
extras = ' target="_blank" rel="noopener noreferrer"' if external else ""
return f'{escape(str(text))}'
@Component
def LocalLink(
text: object,
target: object,
*,
section: str | int | float | None = None,
) -> str:
"""Link to a page by number, title, or the decorated page function itself."""
page = registry.resolve_page(target, section=section) # type: ignore[arg-type]
href = f"#/page/{quote(page.number, safe='.')}"
return (
f''
f"{escape(str(text))}"
)
# Short alias matching the original API idea.
LocLink = LocalLink
@Component
def Code(code: object, language: str = "") -> str:
language_class = f' class="language-{escape(language, quote=True)}"' if language else ""
return f"