Skip to content
Feeding a clanker? Grab this page as raw .md

TangleLatex API#

TangleLatex renders a KaTeX formula in which named numbers are draggable. Mark them with \tangle{name} inside latex and configure each name in parameters; a parameter can show its formatted number or stay symbolic until it is dragged or edited, and repeated markers share one value. The live numbers land in values while you drag, so downstream cells recompute as the equation changes.

See also: Tangle widgets for the same drag gesture in plain prose, Matrix for editing numbers as a grid, and Slider2D for two coupled parameters on one canvas.

Bases: AnyWidget

Render a KaTeX formula with draggable named numeric parameters.

Put \tangle{name} markers in latex and configure each name in parameters. A parameter can display its formatted number directly or remain symbolic until it is dragged or edited. Repeated markers share one value and update together.

Examples:

import marimo as mo
from wigglystuff import TangleLatex

formula = mo.ui.anywidget(
    TangleLatex(
        latex=r"f(x) =  angle{a}x^2 +   angle{b}x +     angle{a}",
        parameters={
            "a": {
                "value": 2.5,
                "min_value": -5,
                "max_value": 5,
                "step": 0.1,
                "display": "symbol",
            },
            "b": {
                "value": 1,
                "min_value": -10,
                "max_value": 10,
                "step": 0.5,
                "display": "symbol",
            },
        },
        reveal_all_on_drag=True,
    )
)
formula

Create a TangleLatex widget.

Parameters:

Name Type Description Default
latex str

KaTeX source containing one or more \tangle{name} markers.

required
parameters Mapping[str, Mapping[str, Any]]

Mapping from marker name to its numeric configuration. value is required. Optional keys are min_value, max_value, step, digits, display ("number" or "symbol"), symbol, label, pixels_per_step, and color (a CSS string or {"light": ..., "dark": ...}).

required
display_mode bool

Render using KaTeX display mode.

True
editor str

Numeric click editor style: "popover" or "inline".

'popover'
reveal_all_on_drag bool

Reveal every symbolic parameter as a number while any parameter is actively dragged. When false, reveal only the selected parameter.

False
theme str

Color theme: "auto", "light", or "dark".

'auto'
**kwargs Any

Forwarded to anywidget.AnyWidget.

{}
Source code in wigglystuff/tangle_latex.py
def __init__(
    self,
    latex: str,
    parameters: Mapping[str, Mapping[str, Any]],
    *,
    display_mode: bool = True,
    editor: str = "popover",
    reveal_all_on_drag: bool = False,
    theme: str = "auto",
    **kwargs: Any,
) -> None:
    """Create a TangleLatex widget.

    Args:
        latex: KaTeX source containing one or more ``\\tangle{name}`` markers.
        parameters: Mapping from marker name to its numeric configuration.
            ``value`` is required. Optional keys are ``min_value``,
            ``max_value``, ``step``, ``digits``, ``display`` (``"number"``
            or ``"symbol"``), ``symbol``, ``label``, ``pixels_per_step``,
            and ``color`` (a CSS string or ``{"light": ..., "dark": ...}``).
        display_mode: Render using KaTeX display mode.
        editor: Numeric click editor style: ``"popover"`` or ``"inline"``.
        reveal_all_on_drag: Reveal every symbolic parameter as a number while
            any parameter is actively dragged. When false, reveal only the
            selected parameter.
        theme: Color theme: ``"auto"``, ``"light"``, or ``"dark"``.
        **kwargs: Forwarded to ``anywidget.AnyWidget``.
    """
    if not isinstance(latex, str):
        raise ValueError("latex must be a string.")
    if editor not in {"popover", "inline"}:
        raise ValueError("editor must be 'popover' or 'inline'.")
    if theme not in {"auto", "light", "dark"}:
        raise ValueError("theme must be 'auto', 'light', or 'dark'.")

    marker_names = set(_MARKER_RE.findall(latex))
    if not marker_names:
        raise ValueError("latex must contain at least one \\tangle{name} marker.")
    normalized = _normalize_parameters(parameters)
    configured_names = set(normalized)
    missing = sorted(marker_names - configured_names)
    unused = sorted(configured_names - marker_names)
    if missing:
        raise ValueError(
            "missing configuration for parameter marker(s): " + ", ".join(missing)
        )
    if unused:
        raise ValueError(
            "parameter configuration not referenced by latex: " + ", ".join(unused)
        )

    values = {name: spec["value"] for name, spec in normalized.items()}
    super().__init__(
        latex=latex,
        parameters=normalized,
        values=values,
        display_mode=display_mode,
        editor=editor,
        reveal_all_on_drag=reveal_all_on_drag,
        theme=theme,
        **kwargs,
    )

Synced traitlets#

Traitlet Type Notes
latex str LaTeX source containing \tangle{name} markers.
parameters dict Per-parameter config (value, bounds, step, digits, color, symbol, ...).
values dict Live current value for each parameter; updates while dragging.
display_mode bool Render the formula in display mode.
editor str Exact-value editor style: "popover" or "inline".
reveal_all_on_drag bool Reveal every tangle value while dragging any one of them.
theme str "auto", "light", or "dark".
error str Validation/render error surfaced from the widget.