topmark.cli.presentation¶
CLI presentation layer for semantic styling.
This module maps backend-agnostic semantic style roles
(StyleRole) to concrete terminal styling callables
(currently backed by yachalk).
Design goals
- Keep all ANSI / terminal styling confined to the CLI layer.
- Centralize the mapping from semantic roles → concrete styles.
- Allow theming and stackable style overrides.
- Keep core and rendering layers free of presentation backends.
Key concepts¶
StyleRole: Semantic meaning (ERROR, WARNING, CHANGED, etc.).Theme: A mapping fromStyleRoleto a concrete text styler.DEFAULT_THEME: The built-in theme used by default.style_for_role(role, theme=...): Resolve a styler for a role.
Theme and overrides¶
Themes support stackable overrides. A Theme consists of:
- `base`: The default mapping from `StyleRole` → styler.
- `overrides`: Optional per-role overrides.
Lookup order:
overrides → base → no-op (identity function)
Example: custom theme with overrides¶
from yachalk import chalk
from topmark.cli.presentation import Theme, DEFAULT_THEME, style_for_role
from topmark.core.presentation import StyleRole
custom_theme = Theme(
base=DEFAULT_THEME.base,
overrides={
StyleRole.ERROR: chalk.bg_red.white.bold,
StyleRole.WARNING: chalk.yellow,
},
)
styler = style_for_role(StyleRole.ERROR, theme=custom_theme)
print(styler("Something went wrong"))
Stacking overrides¶
Overrides can be layered by reusing the same base mapping and adding new override dictionaries:
soft_theme = Theme(
base=DEFAULT_THEME.base,
overrides={
StyleRole.CHANGED: chalk.cyan,
},
)
minimal_theme = Theme(
base=soft_theme.base,
overrides={
StyleRole.ERROR: chalk.red,
},
)
This design keeps styling flexible while maintaining a single semantic source of truth(StyleRole)
across the application.
Theme
dataclass
¶
Theme for mapping StyleRole values to concrete terminal stylers.
A theme consists of a required base mapping plus optional per-role overrides.
Lookups are performed in this order
1) overrides (if provided)
2) base mapping
3) _noop fallback
This keeps the default styling stable while allowing caller-controlled theming (e.g., alternate palettes, accessibility themes, tests).
Attributes:
| Name | Type | Description |
|---|---|---|
base |
Mapping[StyleRole, TextStyler]
|
Base mapping from |
overrides |
Mapping[StyleRole, TextStyler] | None
|
Optional role-specific overrides. |
styler_for ¶
Return the concrete TextStyler for a semantic role.
Source code in src/topmark/cli/presentation.py
no_style_for_role ¶
style_for_role ¶
Return a string styler for the given semantic StyleRole.
This function maps core semantic roles onto concrete terminal styling.
It is intentionally CLI-only (depends on yachalk).
Callers should still gate styling themselves when color is disabled and fall back to a no-op.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
role
|
StyleRole
|
The semantic style role to map. |
required |
styled
|
bool
|
Whether to render styled. |
True
|
theme
|
Theme
|
Theme used to resolve the concrete |
DEFAULT_THEME
|
Returns:
| Type | Description |
|---|---|
TextStyler
|
A callable that styles a string. |
Source code in src/topmark/cli/presentation.py
maybe_style ¶
Conditionally apply a styling function.
This is a tiny helper used by TEXT emitters to avoid scattering if color: checks throughout
rendering code.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
Input text to render. |
required |
styler
|
TextStyler
|
Callable that applies styling to a string (for example, a |
required |
styled
|
bool
|
When False, return |
required |
Returns:
| Type | Description |
|---|---|
str
|
Styled text when enabled; otherwise the original |