Styling
momapy.styling
Classes and functions for styling layout elements using style sheets.
This subpackage provides a CSS-like styling system for layout elements, supporting:
- Style sheets with selectors (type, class, id, child, descendant, compound)
- Style collections that group related style properties
- CSS parsing from files or strings
- Style application to layout elements
Examples:
from momapy.styling import StyleSheet, apply_style_sheet
stylesheet = StyleSheet.from_file("styles.css")
styled_element = apply_style_sheet(element, stylesheet)
Modules:
| Name | Description |
|---|---|
core |
Implementation of the CSS-like styling system. |
Classes:
| Name | Description |
|---|---|
ChildSelector |
Selector that matches elements that are direct children of a parent. |
ClassSelector |
Selector that matches elements by class (including subclasses). |
CompoundSelector |
Selector that matches only if all of its component selectors match (AND logic). |
DescendantSelector |
Selector that matches elements that are descendants of an ancestor. |
IdSelector |
Selector that matches elements by their id attribute. |
NotSelector |
Selector that matches if none of its component selectors match (NOT logic). |
OrSelector |
Selector that matches if any of its component selectors match (OR logic). |
Selector |
Abstract base class for CSS-like selectors. |
StyleCollection |
A dictionary-based collection of style properties. |
StyleSheet |
A dictionary-based stylesheet mapping selectors to style collections. |
TypeSelector |
Selector that matches elements by their exact class name. |
Functions:
| Name | Description |
|---|---|
apply_style_collection |
Apply a StyleCollection to a layout element. |
apply_style_sheet |
Apply a StyleSheet to a layout element or map layout recursively. |
combine_style_sheets |
Merge multiple StyleSheets into a single StyleSheet. |
get_stylable_attributes |
Return the CSS-style names of stylable attributes of a layout element. |
ChildSelector
dataclass
Bases: Selector
Selector that matches elements that are direct children of a parent.
Attributes:
| Name | Type | Description |
|---|
Examples:
selector = ChildSelector(TypeSelector("Group"), TypeSelector("Rectangle"))
selector.match(rect, [group]) # True if rect is direct child of group
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
parent_selector
|
Selector
|
The parent selector |
required |
child_selector
|
Selector
|
The child selector |
required |
Methods:
| Name | Description |
|---|---|
select |
Check if the object is a direct child matching the criteria. |
select
select(obj: LayoutElement | Builder, ancestors: Collection[LayoutElement | Builder]) -> bool
Check if the object is a direct child matching the criteria.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
obj
|
LayoutElement | Builder
|
The layout element or builder to test. |
required |
ancestors
|
Collection[LayoutElement | Builder]
|
List of ancestor elements. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if the object matches child_selector and its immediate |
bool
|
parent matches parent_selector. |
Source code in src/momapy/styling/core.py
ClassSelector
dataclass
Bases: Selector
Selector that matches elements by class (including subclasses).
Attributes:
| Name | Type | Description |
|---|
Examples:
selector = ClassSelector("Shape")
selector.match(some_rectangle) # True if Rectangle is a Shape subclass
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
class_name
|
str
|
The name of the class |
required |
Methods:
| Name | Description |
|---|---|
select |
Check if the object is an instance of the specified class. |
select
select(obj: LayoutElement | Builder, ancestors: Collection[LayoutElement | Builder]) -> bool
Check if the object is an instance of the specified class.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
obj
|
LayoutElement | Builder
|
The layout element or builder to test. |
required |
ancestors
|
Collection[LayoutElement | Builder]
|
List of ancestor elements (unused for class matching). |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if the object is an instance of class_name or its subclasses. |
Source code in src/momapy/styling/core.py
CompoundSelector
dataclass
CompoundSelector(selectors: tuple[Selector, ...])
Bases: Selector
Selector that matches only if all of its component selectors match (AND logic).
Attributes:
| Name | Type | Description |
|---|
Examples:
selector = CompoundSelector((TypeSelector("Rectangle"), ClassSelector("Colored")))
selector.match(element) # True if element is Rectangle AND Colored
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
selectors
|
tuple[Selector, ...]
|
The tuple of conjunct selectors |
required |
Methods:
| Name | Description |
|---|---|
select |
Check if all selectors in the tuple match. |
select
select(obj: LayoutElement | Builder, ancestors: Collection[LayoutElement | Builder]) -> bool
Check if all selectors in the tuple match.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
obj
|
LayoutElement | Builder
|
The layout element or builder to test. |
required |
ancestors
|
Collection[LayoutElement | Builder]
|
List of ancestor elements. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if all selectors match the object. |
Source code in src/momapy/styling/core.py
DescendantSelector
dataclass
Bases: Selector
Selector that matches elements that are descendants of an ancestor.
Attributes:
| Name | Type | Description |
|---|
Examples:
selector = DescendantSelector(TypeSelector("Group"), TypeSelector("Text"))
selector.match(text, [subgroup, group]) # True if text is somewhere inside group
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ancestor_selector
|
Selector
|
The ancestor selector |
required |
descendant_selector
|
Selector
|
The descendant selector |
required |
Methods:
| Name | Description |
|---|---|
select |
Check if the object is a descendant matching the criteria. |
select
select(obj: LayoutElement | Builder, ancestors: Collection[LayoutElement | Builder]) -> bool
Check if the object is a descendant matching the criteria.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
obj
|
LayoutElement | Builder
|
The layout element or builder to test. |
required |
ancestors
|
Collection[LayoutElement | Builder]
|
List of ancestor elements. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if the object matches descendant_selector and any ancestor |
bool
|
matches ancestor_selector. |
Source code in src/momapy/styling/core.py
IdSelector
dataclass
Bases: Selector
Selector that matches elements by their id attribute.
Attributes:
| Name | Type | Description |
|---|
Examples:
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
id_
|
str
|
The id |
required |
Methods:
| Name | Description |
|---|---|
select |
Check if the object has the specified id. |
select
select(obj: LayoutElement | Builder, ancestors: Collection[LayoutElement | Builder]) -> bool
Check if the object has the specified id.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
obj
|
LayoutElement | Builder
|
The layout element or builder to test. |
required |
ancestors
|
Collection[LayoutElement | Builder]
|
List of ancestor elements (unused for id matching). |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if the object has an id_ attribute matching the selector. |
Source code in src/momapy/styling/core.py
NotSelector
dataclass
NotSelector(selectors: tuple[Selector, ...])
Bases: Selector
Selector that matches if none of its component selectors match (NOT logic).
Attributes:
| Name | Type | Description |
|---|
Examples:
selector = NotSelector((TypeSelector("Hidden"),))
selector.match(element) # True if element is NOT of type Hidden
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
selectors
|
tuple[Selector, ...]
|
The tuple of negated conjunct selectors |
required |
Methods:
| Name | Description |
|---|---|
select |
Check if none of the selectors in the tuple match. |
select
select(obj: LayoutElement | Builder, ancestors: Collection[LayoutElement | Builder]) -> bool
Check if none of the selectors in the tuple match.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
obj
|
LayoutElement | Builder
|
The layout element or builder to test. |
required |
ancestors
|
Collection[LayoutElement | Builder]
|
List of ancestor elements. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if no selector matches the object. |
Source code in src/momapy/styling/core.py
OrSelector
dataclass
OrSelector(selectors: tuple[Selector, ...])
Bases: Selector
Selector that matches if any of its component selectors match (OR logic).
Attributes:
| Name | Type | Description |
|---|
Examples:
selector = OrSelector((TypeSelector("Rectangle"), TypeSelector("Circle")))
selector.match(some_shape) # True if shape is Rectangle OR Circle
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
selectors
|
tuple[Selector, ...]
|
The tuple of disjunct selectors |
required |
Methods:
| Name | Description |
|---|---|
select |
Check if any selector in the tuple matches. |
select
select(obj: LayoutElement | Builder, ancestors: Collection[LayoutElement | Builder]) -> bool
Check if any selector in the tuple matches.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
obj
|
LayoutElement | Builder
|
The layout element or builder to test. |
required |
ancestors
|
Collection[LayoutElement | Builder]
|
List of ancestor elements. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if any selector matches the object. |
Source code in src/momapy/styling/core.py
Selector
dataclass
Bases: object
Abstract base class for CSS-like selectors.
Selectors determine whether a layout element matches specific criteria. All selector types inherit from this class and implement the select() method.
Methods:
| Name | Description |
|---|---|
select |
Check if the layout element matches this selector. |
select
abstractmethod
select(obj: LayoutElement | Builder, ancestors: Collection[LayoutElement | Builder]) -> bool
Check if the layout element matches this selector.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
obj
|
LayoutElement | Builder
|
The layout element or builder to test. |
required |
ancestors
|
Collection[LayoutElement | Builder]
|
List of ancestor elements. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if the element matches, False otherwise. |
Source code in src/momapy/styling/core.py
StyleCollection
Bases: dict
A dictionary-based collection of style properties.
StyleCollection maps attribute names to their values, similar to a CSS declaration block. It is used within StyleSheets to store styles for specific selectors.
Examples:
StyleSheet
Bases: dict
A dictionary-based stylesheet mapping selectors to style collections.
StyleSheet extends dict to map Selector objects to StyleCollection objects. Supports merging stylesheets using the | operator.
Examples:
from momapy.styling import StyleSheet, TypeSelector
ss = StyleSheet({TypeSelector("Rectangle"): StyleCollection({"fill": "blue"})})
# Merge stylesheets
combined = ss | another_stylesheet
Methods:
| Name | Description |
|---|---|
from_file |
Parse and return a StyleSheet from a CSS file. |
from_files |
Parse and combine multiple CSS files into a single StyleSheet. |
from_string |
Parse and return a StyleSheet from a CSS string. |
from_file
classmethod
from_file(file_path: str | PathLike) -> StyleSheet
Parse and return a StyleSheet from a CSS file.
Relative @import paths inside the CSS file are resolved against
the directory of file_path, not against the process working
directory.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
file_path
|
str | PathLike
|
Path to the CSS file to parse. |
required |
Returns:
| Type | Description |
|---|---|
StyleSheet
|
A StyleSheet containing the parsed selectors and style collections. |
Raises:
| Type | Description |
|---|---|
ParseException
|
If the CSS file is malformed. |
Source code in src/momapy/styling/core.py
from_files
classmethod
from_files(file_paths: Collection[str]) -> StyleSheet
Parse and combine multiple CSS files into a single StyleSheet.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
file_paths
|
Collection[str]
|
Collection of paths to CSS files. |
required |
Returns:
| Type | Description |
|---|---|
StyleSheet
|
A merged StyleSheet containing all parsed styles. |
Source code in src/momapy/styling/core.py
from_string
classmethod
from_string(s: str) -> StyleSheet
Parse and return a StyleSheet from a CSS string.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
s
|
str
|
CSS string to parse. |
required |
Returns:
| Type | Description |
|---|---|
StyleSheet
|
A StyleSheet containing the parsed selectors and style collections. |
Raises:
| Type | Description |
|---|---|
ParseException
|
If the CSS string is malformed. |
Examples:
Source code in src/momapy/styling/core.py
TypeSelector
dataclass
Bases: Selector
Selector that matches elements by their exact class name.
Attributes:
| Name | Type | Description |
|---|
Examples:
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
class_name
|
str
|
The name of the class |
required |
Methods:
| Name | Description |
|---|---|
select |
Check if the object's class name matches exactly. |
select
select(obj: LayoutElement | Builder, ancestors: Collection[LayoutElement | Builder]) -> bool
Check if the object's class name matches exactly.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
obj
|
LayoutElement | Builder
|
The layout element or builder to test. |
required |
ancestors
|
Collection[LayoutElement | Builder]
|
List of ancestor elements (unused for type matching). |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if the object's class name or builder name matches. |
Source code in src/momapy/styling/core.py
apply_style_collection
apply_style_collection(layout_element: LayoutElement | Builder, style_collection: StyleCollection, strict: bool = True) -> LayoutElement | Builder
Apply a StyleCollection to a layout element.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
layout_element
|
LayoutElement | Builder
|
The element or builder to apply styles to. |
required |
style_collection
|
StyleCollection
|
The styles to apply. |
required |
strict
|
bool
|
If True, raises AttributeError for invalid attributes. If False, silently ignores them. |
True
|
Returns:
| Type | Description |
|---|---|
LayoutElement | Builder
|
The modified layout element or builder. |
Raises:
| Type | Description |
|---|---|
AttributeError
|
If strict=True and an attribute doesn't exist on the element. |
Source code in src/momapy/styling/core.py
apply_style_sheet
apply_style_sheet(map_or_layout_element: Map | LayoutElement | Builder, style_sheet: StyleSheet, strict: bool = True, ancestors: Collection[LayoutElement | Builder] = None) -> Map | LayoutElement | Builder
Apply a StyleSheet to a layout element or map layout recursively.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
map_or_layout_element
|
Map | LayoutElement | Builder
|
The map, element, or builder to style. |
required |
style_sheet
|
StyleSheet
|
The stylesheet to apply. |
required |
strict
|
bool
|
If True, raises errors for invalid attributes. |
True
|
ancestors
|
Collection[LayoutElement | Builder]
|
Internal list of ancestor elements for selector matching. |
None
|
Returns:
| Type | Description |
|---|---|
Map | LayoutElement | Builder
|
The modified map, layout element, or builder. |
Source code in src/momapy/styling/core.py
combine_style_sheets
combine_style_sheets(style_sheets: Collection[StyleSheet]) -> StyleSheet
Merge multiple StyleSheets into a single StyleSheet.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
style_sheets
|
Collection[StyleSheet]
|
Collection of StyleSheets to merge. |
required |
Returns:
| Type | Description |
|---|---|
StyleSheet
|
A combined StyleSheet, or None if the input is empty. |
Source code in src/momapy/styling/core.py
get_stylable_attributes
get_stylable_attributes(layout_element_or_class: LayoutElement | type, presentation_only: bool = False) -> list[str]
Return the CSS-style names of stylable attributes of a layout element.
Returns the names of all dataclass fields that can be set via a
stylesheet (i.e., via apply_style_collection), formatted as
CSS property names (with hyphens instead of underscores).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
layout_element_or_class
|
LayoutElement | type
|
A layout element instance or class to inspect. |
required |
presentation_only
|
bool
|
If True, only return presentation attributes (fill, stroke, font, transform, etc.). Defaults to False. |
False
|
Returns:
| Type | Description |
|---|---|
list[str]
|
A sorted list of CSS-style attribute names. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If the argument is not a LayoutElement class or instance. |