1"""
2The public HTML and JavaScript minifier entry points and the JavaScript options object.
3
4:func:`minify` parses an HTML document and serializes it back through the shipped C
5minifier (the :class:`~turbohtml.Minify` layout), the one-call convenience ``minify-html``
6and ``htmlmin`` expose; every transform is round-trip safe, so the output reparses to the
7same tree. :func:`minify_js` is the separate JavaScript minifier: the C extension exposes
8only the numeric seam ``_minify_js(source, fold, mangle)``, and this layer gives it a typed,
9defaulted surface plus the :class:`JSMinify` options object that the HTML serializer's
10``Minify(minify_js=...)`` hook also accepts, so the standalone call and the
11inline-``<script>`` path are configured the same way.
12"""
13
14from __future__ import annotations
15
16from typing import Final, Literal
17
18from turbohtml._html import Minify, _minify_js, parse
19
20from ._jsminify import JSMinify
21from ._render import Html
22
23__all__ = ["JSMinify", "Minify", "minify", "minify_js"]
24
25_DEFAULT: Final = Minify()
26
27
28def minify(html: str, options: Minify | None = None) -> str:
29 """
30 Minify an HTML document.
31
32 Parse ``html`` into a tree and serialize it with the minifying layout, folding insignificant whitespace, omitting
33 the start/end tags the WHATWG rules make optional, dropping redundant attribute quotes, and stripping comments. Each
34 transform is round-trip safe, so the result reparses to the same tree and minifying is idempotent.
35
36 :param html: the HTML document to minify.
37 :param options: which folds to apply; ``None`` engages every transform (the :class:`~turbohtml.Minify` default).
38 :returns: the minified HTML.
39 """
40 return parse(html).serialize(Html(layout=options if options is not None else _DEFAULT))
41
42
43def minify_js(source: str, options: JSMinify | None = None, on_error: Literal["raise", "passthrough"] = "raise") -> str:
44 """
45 Minify a JavaScript source string, returning the shortest equivalent program.
46
47 Every transform preserves semantics, so the result evaluates identically to ``source``.
48 ``options`` defaults to the full pipeline (fold and mangle).
49
50 ``on_error`` chooses what happens when the parser cannot handle the script. The default
51 ``"raise"`` fails loudly; ``"passthrough"`` returns ``source`` unchanged instead, the
52 never-fail contract ``jsmin`` and ``rjsmin`` guarantee -- the same verbatim fallback the
53 inline-``<script>`` path already applies so one bad script cannot break serialization.
54
55 :param source: the JavaScript source to minify.
56 :param options: which optional passes to run; ``None`` runs the full pipeline.
57 :param on_error: ``"raise"`` (default) to raise on a script the parser cannot handle, or
58 ``"passthrough"`` to return ``source`` unchanged.
59 :returns: the minified JavaScript, or ``source`` verbatim when it is unparsable and
60 ``on_error="passthrough"``.
61 :raises TypeError: if ``source`` is not a :class:`str`.
62 :raises ValueError: if ``on_error`` is not ``"raise"`` or ``"passthrough"``, or -- when
63 ``on_error="raise"`` -- if the parser cannot handle the script (a lexical or syntax error,
64 or input nested past the depth limit), with the message naming the construct, its byte
65 offset, and the offending token.
66 """
67 return _minify_js(source, (config := options or JSMinify()).fold, config.mangle, on_error)