# html

URL: /kida/api/utils/html/
Section: utils
Description: HTML utilities for Kida template engine.

Provides optimized HTML escaping, the Markup safe-string class, and related utilities.
Zero external dependencies — pure Python 3.14+.

Security Hardening (RFC: Markup Security Hardening):
- NUL byte stripping in all escaping
- O(1) frozenset lookups for character classes
- Attribute name validation in xmlattr()
- Event handler attribute warnings
- Context-specific escaping (JS, CSS, URL)

All operations are O(n) single-pass with no ReDoS risk.

---

> For a complete page index, fetch /kida/llms.txt.

Open LLM text
(/kida/api/utils/html/index.txt)

Share with AI

Ask Claude
(https://claude.ai/new?q=Please%20help%20me%20understand%20this%20documentation%3A%20%2Fkida%2Fapi%2Futils%2Fhtml%2Findex.txt)

Ask ChatGPT
(https://chatgpt.com/?q=Please%20help%20me%20understand%20this%20documentation%3A%20%2Fkida%2Fapi%2Futils%2Fhtml%2Findex.txt)

Ask Gemini
(https://gemini.google.com/app?q=Please%20help%20me%20understand%20this%20documentation%3A%20%2Fkida%2Fapi%2Futils%2Fhtml%2Findex.txt)

Ask Copilot
(https://copilot.microsoft.com/?q=Please%20help%20me%20understand%20this%20documentation%3A%20%2Fkida%2Fapi%2Futils%2Fhtml%2Findex.txt)

Module

#
`utils.html`

HTML utilities for Kida template engine.

Provides optimized HTML escaping, the Markup safe-string class, and related utilities.
Zero external dependencies — pure Python 3.14+.

Security Hardening (RFC: Markup Security Hardening):

- NUL byte stripping in all escaping

- O(1) frozenset lookups for character classes

- Attribute name validation in xmlattr()

- Event handler attribute warnings

- Context-specific escaping (JS, CSS, URL)

All operations are O(n) single-pass with no ReDoS risk.

3Classes10Functions

## Classes

`Markup`

34

▼

A string subclass marking content as safe (won't be auto-escaped).

The Markup class implements the…

A string subclass marking content as safe (won't be auto-escaped).

The Markup class implements the`__html__`protocol used by template engines
to identify pre-escaped content. When combined with regular strings via
operators like`+`, the non-Markup strings are automatically escaped.

This is Kida's native implementation — no external dependencies required.

#### Methods

`format`

2

`Self`

▼

Format string, escaping non-Markup arguments.

`def format(self, *args: Any, **kwargs: Any) -> Self`

##### Parameters

Name
Type
Description

`*args`
`—`

`**kwargs`
`—`

##### Returns

`Self`

`join`

1

`Self`

▼

Join sequence, escaping non-Markup elements.

`def join(self, seq: Iterable[str]) -> Self`

##### Parameters

Name
Type
Description

`seq`
`—`

##### Returns

`Self`

`capitalize`

0

`Self`

▼

`def capitalize(self) -> Self`

##### Returns

`Self`

`casefold`

0

`Self`

▼

`def casefold(self) -> Self`

##### Returns

`Self`

`center`

2

`Self`

▼

`def center(self, width: SupportsIndex, fillchar: str = ' ') -> Self`

##### Parameters

Name
Type
Description

`width`
`—`

`fillchar`
`—`

Default:`' '`

##### Returns

`Self`

`lower`

0

`Self`

▼

`def lower(self) -> Self`

##### Returns

`Self`

`upper`

0

`Self`

▼

`def upper(self) -> Self`

##### Returns

`Self`

`title`

0

`Self`

▼

`def title(self) -> Self`

##### Returns

`Self`

`swapcase`

0

`Self`

▼

`def swapcase(self) -> Self`

##### Returns

`Self`

`strip`

1

`Self`

▼

`def strip(self, chars: str | None = None) -> Self`

##### Parameters

Name
Type
Description

`chars`
`—`

Default:`None`

##### Returns

`Self`

`lstrip`

1

`Self`

▼

`def lstrip(self, chars: str | None = None) -> Self`

##### Parameters

Name
Type
Description

`chars`
`—`

Default:`None`

##### Returns

`Self`

`rstrip`

1

`Self`

▼

`def rstrip(self, chars: str | None = None) -> Self`

##### Parameters

Name
Type
Description

`chars`
`—`

Default:`None`

##### Returns

`Self`

`ljust`

2

`Self`

▼

`def ljust(self, width: SupportsIndex, fillchar: str = ' ') -> Self`

##### Parameters

Name
Type
Description

`width`
`—`

`fillchar`
`—`

Default:`' '`

##### Returns

`Self`

`rjust`

2

`Self`

▼

`def rjust(self, width: SupportsIndex, fillchar: str = ' ') -> Self`

##### Parameters

Name
Type
Description

`width`
`—`

`fillchar`
`—`

Default:`' '`

##### Returns

`Self`

`zfill`

1

`Self`

▼

`def zfill(self, width: SupportsIndex) -> Self`

##### Parameters

Name
Type
Description

`width`
`—`

##### Returns

`Self`

`replace`

3

`Self`

▼

`def replace(self, old: str, new: str, count: SupportsIndex = -1) -> Self`

##### Parameters

Name
Type
Description

`old`
`—`

`new`
`—`

`count`
`—`

Default:`-1`

##### Returns

`Self`

`expandtabs`

1

`Self`

▼

`def expandtabs(self, tabsize: SupportsIndex = 8) -> Self`

##### Parameters

Name
Type
Description

`tabsize`
`—`

Default:`8`

##### Returns

`Self`

`split`

2

`list[Self]`

▼

`def split(self, sep: str | None = None, maxsplit: SupportsIndex = -1) -> list[Self]`

##### Parameters

Name
Type
Description

`sep`
`—`

Default:`None`

`maxsplit`
`—`

Default:`-1`

##### Returns

`list[Self]`

`rsplit`

2

`list[Self]`

▼

`def rsplit(self, sep: str | None = None, maxsplit: SupportsIndex = -1) -> list[Self]`

##### Parameters

Name
Type
Description

`sep`
`—`

Default:`None`

`maxsplit`
`—`

Default:`-1`

##### Returns

`list[Self]`

`splitlines`

1

`list[Self]`

▼

`def splitlines(self, keepends: bool = False) -> list[Self]`

##### Parameters

Name
Type
Description

`keepends`
`—`

Default:`False`

##### Returns

`list[Self]`

`partition`

1

`tuple[Self, Self, Self]`

▼

`def partition(self, sep: str) -> tuple[Self, Self, Self]`

##### Parameters

Name
Type
Description

`sep`
`—`

##### Returns

`tuple[Self, Self, Self]`

`rpartition`

1

`tuple[Self, Self, Self]`

▼

`def rpartition(self, sep: str) -> tuple[Self, Self, Self]`

##### Parameters

Name
Type
Description

`sep`
`—`

##### Returns

`tuple[Self, Self, Self]`

`striptags`

0

`Self`

▼

Remove HTML tags from the string.

**IMPORTANT: This is for DISPLAY purposes on…

`def striptags(self) -> Self`

Remove HTML tags from the string.

IMPORTANT: This is for DISPLAY purposes only, not security.

This method uses regex-based tag removal which can be bypassed
with malformed HTML. It is suitable for:

- Displaying text previews

- Extracting text content for search indexing

- Formatting plain-text emails from HTML

For security (preventing XSS), always use html_escape() or the
Markup class with autoescape enabled.

##### Returns

`Self`

Markup with all HTML tags removed.

`unescape`

0

`str`

▼

Convert HTML entities back to characters.

`def unescape(self) -> str`

##### Returns

`str`

Plain string with entities decoded (no longer marked as safe).

`escape`

1

`Self`

▼

Escape a value and wrap it as Markup.

This is the class method form of escapin…

classmethod

`def escape(cls, value: Any) -> Self`

Escape a value and wrap it as Markup.

This is the class method form of escaping — use for explicit escaping.

##### Parameters

Name
Type
Description

`value`
`—`

Value to escape. Objects with`__html__()`are used as-is.

##### Returns

`Self`

Markup instance with the escaped content.

Internal Methods
9

▼

`__new__`

1

`Self`

▼

Create a Markup string.

`def __new__(cls, value: Any = '') -> Self`

##### Parameters

Name
Type
Description

`value`
`—`

Content to mark as safe. If it has an`__html__()`method, that method is called to get the string value.

Default:`''`

##### Returns

`Self`

Markup instance containing the safe content.

`__html__`

0

`Self`

▼

Return self — already safe content.

This method is the `__html__` protocol tha…

`def __html__(self) -> Self`

Return self — already safe content.

This method is the`__html__`protocol that template engines use
to detect pre-escaped content.

##### Returns

`Self`

`__markdown__`

0

`Self`

▼

Return self — already safe content for markdown autoescape too.

Lets `{{ value…

`def __markdown__(self) -> Self`

Return self — already safe content for markdown autoescape too.

Lets`{{ value | safe }}`opt out of escaping in markdown mode the
same way it does in HTML mode.

##### Returns

`Self`

`__repr__`

0

`str`

▼

`def __repr__(self) -> str`

##### Returns

`str`

`__add__`

1

`Self`

▼

Concatenate, escaping `other` if not Markup.

`def __add__(self, other: str) -> Self`

##### Parameters

Name
Type
Description

`other`
`—`

##### Returns

`Self`

`__radd__`

1

`Self`

▼

Reverse concatenate, escaping `other` if not Markup.

`def __radd__(self, other: str) -> Self`

##### Parameters

Name
Type
Description

`other`
`—`

##### Returns

`Self`

`__mul__`

1

`Self`

▼

Repeat string n times.

`def __mul__(self, n: SupportsIndex) -> Self`

##### Parameters

Name
Type
Description

`n`
`—`

##### Returns

`Self`

`__rmul__`

1

`Self`

▼

Repeat string n times (reverse).

`def __rmul__(self, n: SupportsIndex) -> Self`

##### Parameters

Name
Type
Description

`n`
`—`

##### Returns

`Self`

`__mod__`

1

`Self`

▼

Format string with %-style, escaping non-Markup args.

`def __mod__(self, args: Any) -> Self`

##### Parameters

Name
Type
Description

`args`
`—`

##### Returns

`Self`

`JSString`

2

▼

A string safe for JavaScript string literal context.

Similar to Markup but for JavaScript strings …

A string safe for JavaScript string literal context.

Similar to Markup but for JavaScript strings instead of HTML.
Prevents accidental double-escaping in JS contexts.

#### Methods

Internal Methods
2

▼

`__new__`

1

`Self`

▼

`def __new__(cls, value: Any = '') -> Self`

##### Parameters

Name
Type
Description

`value`
`—`

Default:`''`

##### Returns

`Self`

`__repr__`

0

`str`

▼

`def __repr__(self) -> str`

##### Returns

`str`

`SoftStr`

6

▼

A string wrapper that defers __str__ evaluation.

Useful for expensive string operations that may n…

A string wrapper that defers str evaluation.

Useful for expensive string operations that may not be needed.
Commonly used with missing template variables or expensive lookups.

Thread-Safety:
The lazy evaluation is NOT thread-safe. If you need thread-safe
lazy evaluation, compute the value before passing to templates.

#### Methods

Internal Methods
6

▼

`__init__`

1

▼

`def __init__(self, func: Callable[[], str]) -> None`

##### Parameters

Name
Type
Description

`func`
`—`

`__str__`

0

`str`

▼

`def __str__(self) -> str`

##### Returns

`str`

`__html__`

0

`str`

▼

Support __html__ protocol - escape when rendered.

Handles the case where _func…

`def __html__(self) -> str`

Support html protocol - escape when rendered.

Handles the case where _func returns Markup properly.

##### Returns

`str`

`__repr__`

0

`str`

▼

`def __repr__(self) -> str`

##### Returns

`str`

`__bool__`

0

`bool`

▼

`def __bool__(self) -> bool`

##### Returns

`bool`

`__len__`

0

`int`

▼

`def __len__(self) -> int`

##### Returns

`int`

## Functions

`html_escape`

1

`str`

▼

O(n) single-pass HTML escaping with type optimization.

Returns plain str (for …

`def html_escape(value: Any) -> str`

O(n) single-pass HTML escaping with type optimization.

Returns plain str (for template._escape use).

Complexity: O(n) single-pass using str.translate().

Security:

- Escapes &, <, >, ", '

- Strips NUL bytes () in the same translate pass

- Objects with html() are returned as-is (already safe)

Optimizations:

- Fast path for plain str (type check excludes Markup subclass)

- Skip Markup objects (already safe)

- Skip numeric types (int, float, bool) - cannot contain HTML chars

- Single-pass translation handles escaping + NUL stripping together

##### Parameters

Name
Type
Description

`value`
`Any`

Value to escape (will be converted to string)

##### Returns

`str`

`html_escape_filter`

1

`Markup`

▼

HTML escape returning Markup (for filter use).

Returns Markup object so result…

`def html_escape_filter(value: Any) -> Markup`

HTML escape returning Markup (for filter use).

Returns Markup object so result won't be escaped again by autoescape.

##### Parameters

Name
Type
Description

`value`
`Any`

Value to escape (will be converted to string)

##### Returns

`Markup`

`xmlattr`

4

`Markup`

▼

Convert dict to XML/HTML attributes string.

Escapes attribute values and forma…

`def xmlattr(value: dict[str, Any], *, allow_events: bool = False, strip_events: bool = False, strict: bool = True) -> Markup`

Convert dict to XML/HTML attributes string.

Escapes attribute values and formats as key="value" pairs.
Returns Markup to prevent double-escaping when autoescape is enabled.

Attribute ordering: Python 3.7+ dicts maintain insertion order.
Output order matches input dict order.

Security:

- Validates attribute names per HTML5 spec

- Warns on event handler attributes (onclick, onerror, etc.)

- Escapes all attribute values

##### Parameters

Name
Type
Description

`value`
`dict[str, Any]`

Dictionary of attribute names to values.

`allow_events`
`bool`

If False (default), warns on event handler attributes (onclick, onerror, etc.). Set True to suppress.

Default:`False`

`strip_events`
`bool`

If True, automatically removes event handler attributes. Default False.

Default:`False`

`strict`
`bool`

If True (default), raises on invalid attribute names. If False, skips invalid names with a warning.

Default:`True`

##### Returns

`Markup`

`js_escape`

1

`str`

▼

Escape a value for use inside JavaScript string literals.

This escapes charact…

`def js_escape(value: Any) -> str`

Escape a value for use inside JavaScript string literals.

This escapes characters that could break out of a JS string or
inject code. Use this when embedding user data in inline scripts.

Complexity: O(n) single pass using str.translate().

##### Parameters

Name
Type
Description

`value`
`Any`

Value to escape (will be converted to string).

##### Returns

`str`

`css_escape`

1

`str`

▼

Escape a value for use in CSS contexts.

Protects against breaking out of quote…

`def css_escape(value: Any) -> str`

Escape a value for use in CSS contexts.

Protects against breaking out of quotes in properties or
injecting malicious content into url() or @import.

Complexity: O(n) single pass using str.translate().

##### Parameters

Name
Type
Description

`value`
`Any`

Value to escape.

##### Returns

`str`

`url_is_safe`

2

`bool`

▼

Check if a URL has a safe protocol scheme.

Protects against javascript:, vbscr…

`def url_is_safe(url: str, *, allow_data: bool = False) -> bool`

Check if a URL has a safe protocol scheme.

Protects against javascript:, vbscript:, and data: URLs that
can execute code when used in href/src attributes.

Uses window-based parsing: O(n) single pass, no regex.

##### Parameters

Name
Type
Description

`url`
`str`

URL to check.

`allow_data`
`bool`

If True, allow data: URLs. Default False.

Default:`False`

##### Returns

`bool`

`safe_url`

2

`str`

▼

Return URL if safe, otherwise return fallback.

Use in templates where you need…

`def safe_url(url: str, *, fallback: str = '#') -> str`

Return URL if safe, otherwise return fallback.

Use in templates where you need a safe URL value (href, src, etc.).

##### Parameters

Name
Type
Description

`url`
`str`

URL to validate.

`fallback`
`str`

Value to return if URL is unsafe. Default "#".

Default:`'#'`

##### Returns

`str`

`strip_tags`

1

`str`

▼

Remove HTML tags from string.

**IMPORTANT: This is for DISPLAY purposes only, …

`def strip_tags(value: str) -> str`

Remove HTML tags from string.

IMPORTANT: This is for DISPLAY purposes only, not security.

This function uses regex-based tag removal which can be bypassed
with malformed HTML. It is suitable for:

- Displaying text previews

- Extracting text content for search indexing

- Formatting plain-text emails from HTML

For security (preventing XSS), always use html_escape() or the
Markup class with autoescape enabled.

Uses pre-compiled regex for performance. O(n) single pass.

##### Parameters

Name
Type
Description

`value`
`str`

String potentially containing HTML tags

##### Returns

`str`

`spaceless`

1

`str`

▼

Remove whitespace between HTML tags.

`def spaceless(html_str: str) -> str`

##### Parameters

Name
Type
Description

`html_str`
`str`

HTML string

##### Returns

`str`

`format_html`

3

`Markup`

▼

Format a string with HTML escaping of all arguments.

Like str.format() but esc…

`def format_html(format_string: str, *args: Any, **kwargs: Any) -> Markup`

Format a string with HTML escaping of all arguments.

Like str.format() but escapes all arguments for HTML safety.
The format string itself is trusted (not escaped).

This is a convenience wrapper around Markup().format().

##### Parameters

Name
Type
Description

`format_string`
`str`

Format string (trusted, not escaped). *args: Positional arguments (escaped). **kwargs: Keyword arguments (escaped).

`*args`
`Any`

`**kwargs`
`Any`

##### Returns

`Markup`
