Skip to content

topmark.presentation.markdown.utils

topmark / presentation / markdown / utils

Shared presentation utilities for MARKDOWN.

This module provides helpers to render Markdown fragments.

Scope: - Pure string rendering only (no I/O, no Click/Rich console usage). - Safe to import from any frontend (CLI, API tests, etc.).

The helpers here are intentionally small and composable; command-specific formatting belongs in the command's presentation module.

markdown_code_span

markdown_code_span(text)

Render text as a Markdown inline code span.

This chooses a backtick fence that is one longer than the longest run of backticks in text, which safely supports filenames that contain backticks.

Parameters:

Name Type Description Default
text str

Raw text to wrap.

required

Returns:

Type Description
str

Markdown inline code span.

Source code in src/topmark/presentation/markdown/utils.py
def markdown_code_span(text: str) -> str:
    """Render `text` as a Markdown inline code span.

    This chooses a backtick fence that is one longer than the longest run of
    backticks in `text`, which safely supports filenames that contain backticks.

    Args:
        text: Raw text to wrap.

    Returns:
        Markdown inline code span.
    """
    max_run: int = 0
    run: int = 0
    for ch in text:
        if ch == "`":
            run += 1
            if run > max_run:
                max_run = run
        else:
            run = 0

    fence: str = "`" * (max_run + 1)
    return f"{fence}{text}{fence}"

markdown_escape

markdown_escape(text)

Safely render text as backticked str.

Source code in src/topmark/presentation/markdown/utils.py
def markdown_escape(text: str) -> str:
    """Safely render `text` as backticked str."""
    # Find the longest sequence of backticks in the input
    backtick_sequences = re.findall(r"`+", text)
    max_backticks: int = len(max(backtick_sequences, key=len)) if backtick_sequences else 0

    # Use one more backtick than the max sequence found
    fence: str = "`" * (max_backticks + 1)

    # Add padding spaces if the text starts or ends with a backtick
    padding: str = " " if text.startswith("`") or text.endswith("`") else ""

    return f"{fence}{padding}{text}{padding}{fence}"

render_fenced_code_block_markdown

render_fenced_code_block_markdown(*, text, language=None)

Render a Markdown fenced code block using a collision-safe fence.

Parameters:

Name Type Description Default
text str

Code block content.

required
language str | None

Optional Markdown language identifier.

None

Returns:

Type Description
str

Markdown fenced code block.

Source code in src/topmark/presentation/markdown/utils.py
def render_fenced_code_block_markdown(
    *,
    text: str,
    language: str | None = None,
) -> str:
    """Render a Markdown fenced code block using a collision-safe fence.

    Args:
        text: Code block content.
        language: Optional Markdown language identifier.

    Returns:
        Markdown fenced code block.
    """
    backtick_matches: list[str] = re.findall(r"`{3,}", text)
    fence_len: int = max([len(match) for match in backtick_matches] + [2]) + 1
    fence: str = "`" * fence_len
    opening: str = f"{fence}{language or ''}"

    return "\n".join(
        [
            opening,
            text.rstrip("\n"),
            fence,
        ]
    )

render_markdown_table

render_markdown_table(headers, rows, *, align=None)

Render a GitHub-flavoured Markdown table with padded columns.

Parameters:

Name Type Description Default
headers Sequence[str]

Column headers.

required
rows Sequence[Sequence[str]]

Table rows. Each row must have the same number of columns as headers.

required
align Mapping[int, str] | None

Optional mapping of column index to alignment: "left" (default), "right", or "center".

None

Returns:

Type Description
str

The Markdown table as a single string, ending with a newline.

Notes
  • Widths are computed from the visible string lengths of headers and cells.
  • Alignment uses Markdown syntax: :--- (left), :---: (center), ---: (right).
  • This function is pure string rendering and suitable for reuse in any frontend.

Raises:

Type Description
ValueError

If any row has a different number of columns than headers.

Source code in src/topmark/presentation/markdown/utils.py
def render_markdown_table(
    headers: Sequence[str],
    rows: Sequence[Sequence[str]],
    *,
    align: Mapping[int, str] | None = None,
) -> str:
    """Render a GitHub-flavoured Markdown table with padded columns.

    Args:
        headers: Column headers.
        rows: Table rows. Each row must have the same number of columns as ``headers``.
        align: Optional mapping of column index to alignment: ``"left"`` (default),
            ``"right"``, or ``"center"``.

    Returns:
        The Markdown table as a single string, ending with a newline.

    Notes:
        - Widths are computed from the visible string lengths of headers and cells.
        - Alignment uses Markdown syntax: ``:---`` (left), ``:---:`` (center), ``---:`` (right).
        - This function is pure string rendering and suitable for reuse in any frontend.

    Raises:
        ValueError: If any row has a different number of columns than ``headers``.
    """
    if not headers:
        return ""
    ncols: int = len(headers)
    for r in rows:
        if len(r) != ncols:
            raise ValueError("All rows must have the same number of columns as headers")

    # Compute column widths
    widths: list[int] = [len(str(h)) for h in headers]
    for r in rows:
        for i, cell in enumerate(r):
            widths[i] = max(widths[i], len(str(cell)))

    def _pad(text: str, w: int) -> str:
        return f"{text:<{w}}"

    # Header line
    header_line: str = " | ".join(_pad(str(headers[i]), widths[i]) for i in range(ncols))

    # Separator line with alignment markers
    def _sep_for(i: int) -> str:
        style: str = (align or {}).get(i, "left").lower()
        w: int = max(1, widths[i])
        if style == "right":
            return "-" * (w - 1) + ":" if w > 1 else ":"
        if style == "center":
            return ":" + ("-" * (w - 2) if w > 2 else "-") + ":"
        # left/default
        return "-" * w

    sep_line: str = " | ".join(_sep_for(i) for i in range(ncols))

    # Data lines
    data_lines: list[str] = [
        " | ".join(_pad(str(r[i]), widths[i]) for i in range(ncols)) for r in rows
    ]

    return (
        "| "
        + header_line
        + " |\n"
        + "| "
        + sep_line
        + " |\n"
        + "\n".join("| " + line + " |" for line in data_lines)
        + "\n"
    )

render_toml_markdown

render_toml_markdown(
    *, toml_text, heading, heading_level=2
)

Render a Markdown heading followed by a fenced TOML code block.

Parameters:

Name Type Description Default
toml_text str

TOML content to place inside the fenced code block.

required
heading str | None

Optional heading text without the leading '#'.

required
heading_level int

Heading level (normalized to 1..6).

2

Returns:

Type Description
str

A Markdown string ending with a newline.

Source code in src/topmark/presentation/markdown/utils.py
def render_toml_markdown(
    *,
    toml_text: str,
    heading: str | None,
    heading_level: int = 2,
) -> str:
    """Render a Markdown heading followed by a fenced TOML code block.

    Args:
        toml_text: TOML content to place inside the fenced code block.
        heading: Optional heading text without the leading '#'.
        heading_level: Heading level (normalized to 1..6).

    Returns:
        A Markdown string ending with a newline.
    """
    lines: list[str] = []

    if heading:
        level: int = max(1, min(heading_level, 6))
        lines.append(f"{'#' * level} {heading}\n")

    # Handle nested fences: find the longest backtick chain
    backtick_matches = re.findall(r"`{3,}", toml_text)
    fence_len: int = max([len(m) for m in backtick_matches] + [2]) + 1
    fence: str = "`" * fence_len

    lines.append(f"{fence}toml")
    lines.append(toml_text.strip("\n"))
    lines.append(fence)

    return "\n".join(lines) + "\n"

render_path_display_markdown

render_path_display_markdown(ctx)

Render a short Markdown path label for headings and list items.

This helper formats get_display_path() for Markdown and annotates STDIN-backed content with _(via STDIN)_ when a synthetic filename is available.

Parameters:

Name Type Description Default
ctx ProcessingContext

Processing context containing the path to display.

required

Returns:

Type Description
str

Short Markdown label for per-file headings and guidance messages.

Source code in src/topmark/presentation/markdown/utils.py
def render_path_display_markdown(ctx: ProcessingContext) -> str:
    """Render a short Markdown path label for headings and list items.

    This helper formats
    [`get_display_path()`][topmark.presentation.shared.pipeline.get_display_path]
    for Markdown and annotates STDIN-backed content with ``_(via STDIN)_`` when a
    synthetic filename is available.

    Args:
        ctx: Processing context containing the path to display.

    Returns:
        Short Markdown label for per-file headings and guidance messages.
    """
    path: str = get_display_path(ctx)
    code: str = markdown_code_span(path)

    if ctx.run_options.stdin_mode and bool(ctx.run_options.stdin_filename):
        return f"{code} _(via STDIN)_"

    return code