Source code for montin.core.plugins

"""
montin.core.plugins
=====================
Optional JavaScript libraries a deck can pull in, and how they are loaded.

Declare the ones you need via the :class:`Plugins` container and pass them to
``Deck(plugins=[...])``::

    from montin import Deck, Plugins

    Deck(plugins=[
        Plugins.Plotly(),                       # interactive charts
        Plugins.Mermaid(theme="dark"),          # diagrams
        Plugins.Highlight(style="github-dark"), # code highlighting
        Plugins.MathJax(output="svg"),          # LaTeX math
    ])

Nothing is mandatory — declare only what you use. Each plugin can be loaded from
a CDN (``source="cdn"``, the default) or embedded in the file
(``source="bundled"``) for a report that works with no network at all. The deck
sets the default for all of them via ``Deck(plugin_source=...)``.
"""

from __future__ import annotations

from dataclasses import dataclass
from typing import ClassVar, Literal


[docs] @dataclass class Plugin: """Base class for an optional JS library. Use a :class:`Plugins` subclass. Attributes: source: ``"cdn"`` to load from a content-delivery network, ``"bundled"`` to embed the library in the report (fully offline). ``None`` (default) inherits the deck-wide ``Deck(plugin_source=...)`` setting. version: Pin a specific library version. ``None`` uses the version Montin vendors / knows the CDN URL for. url: A custom URL to load the library from instead of the default CDN — e.g. a company intranet mirror. Only used in ``"cdn"`` mode. name: The library identifier (``"plotly"``, ``"mermaid"``, ...). Set by each subclass; not meant to be overridden. """ source: Literal["cdn", "bundled"] | None = None version: str | None = None url: str | None = None name: ClassVar[str] = ""
[docs] def set_cdn(self, url: str) -> "Plugin": """Load this plugin from ``url`` (sets ``source="cdn"``). Returns self. Convenience for pointing a plugin at a custom mirror in one call:: Plugins.MathJax().set_cdn("https://intranet.local/mathjax/tex-svg.js") """ self.source = "cdn" self.url = url return self
[docs] @dataclass class Plotly(Plugin): """Plotly.js — required by ``slide.add_plotly()``.""" name: ClassVar[str] = "plotly"
[docs] @dataclass class Mermaid(Plugin): """Mermaid — required by ``slide.add_mermaid()``. Attributes: theme: Mermaid theme passed to ``mermaid.initialize`` (e.g. ``"dark"``, ``"default"``, ``"forest"``, ``"neutral"``). """ theme: str = "dark" name: ClassVar[str] = "mermaid"
[docs] @dataclass class Highlight(Plugin): """highlight.js — required by ``slide.add_code()``. Attributes: style: The highlight.js stylesheet name (e.g. ``"github-dark"``, ``"github"``, ``"monokai"``). Selects which CSS theme is loaded. """ style: str = "github-dark" name: ClassVar[str] = "highlight"
[docs] @dataclass class MathJax(Plugin): """MathJax — renders LaTeX math in ``slide.add_text()``. Attributes: output: ``"svg"`` (default) renders math as SVG with the glyphs embedded in the library, so a bundled deck stays a single offline file. ``"chtml"`` uses HTML+CSS with web fonts that are fetched at runtime — slightly nicer text selection, but not single-file offline. """ output: Literal["svg", "chtml"] = "svg" name: ClassVar[str] = "mathjax"
[docs] @dataclass class Tabulator(Plugin): """Tabulator — required by ``slide.add_tabulator()`` (interactive tables). Attributes: theme: which bundled stylesheet to use. ``"auto"`` (default) follows the deck theme — the dark sheet for the ``default``/``dark`` themes, the light sheet for ``light``. Force it with ``"light"`` / ``"dark"``. """ theme: Literal["auto", "light", "dark"] = "auto" name: ClassVar[str] = "tabulator"
class Plugins: """Namespace of the available plugins. Instantiate the one(s) you need:: Deck(plugins=[Plugins.Plotly(), Plugins.MathJax(source="cdn")]) """ Plotly = Plotly Mermaid = Mermaid Highlight = Highlight MathJax = MathJax Tabulator = Tabulator