Styling
momapy.styling
Classes and functions for styling layout elements using style sheets.
This module 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
Example
from momapy.styling import StyleSheet
Load a CSS file
stylesheet = StyleSheet.from_file("styles.css")
Apply to a layout element
styled_element = apply_style_sheet(element, stylesheet)
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. |
ChildSelector
dataclass
Bases: Selector
Selector that matches elements that are direct children of a parent.
Attributes:
| Name | Type | Description |
|---|---|---|
parent_selector |
Selector
|
The selector for the parent element. |
child_selector |
Selector
|
The selector for the child element. |
Example
selector = ChildSelector(TypeSelector("Group"), TypeSelector("Rectangle")) selector.match(rect, [group]) # True if rect is direct child of group
Methods:
| Name | Description |
|---|---|
select |
Check if the object is a direct child matching the criteria. |
select
select(obj: LayoutElement | LayoutElementBuilder, ancestors: Collection[LayoutElement | LayoutElementBuilder])
Check if the object is a direct child matching the criteria.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
obj
|
LayoutElement | LayoutElementBuilder
|
The layout element or builder to test. |
required |
ancestors
|
Collection[LayoutElement | LayoutElementBuilder]
|
List of ancestor elements. |
required |
Returns:
| Type | Description |
|---|---|
|
True if the object matches child_selector and its immediate |
|
|
parent matches parent_selector. |
Source code in src/momapy/styling.py
ClassSelector
dataclass
Bases: Selector
Selector that matches elements by class (including subclasses).
Attributes:
| Name | Type | Description |
|---|---|---|
class_name |
str
|
The class name to match (matches subclasses too). |
Example
selector = ClassSelector("Shape") selector.match(some_rectangle) # True if Rectangle is a Shape subclass
Methods:
| Name | Description |
|---|---|
select |
Check if the object is an instance of the specified class. |
select
select(obj: LayoutElement | LayoutElementBuilder, ancestors: Collection[LayoutElement | LayoutElementBuilder])
Check if the object is an instance of the specified class.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
obj
|
LayoutElement | LayoutElementBuilder
|
The layout element or builder to test. |
required |
ancestors
|
Collection[LayoutElement | LayoutElementBuilder]
|
List of ancestor elements (unused for class matching). |
required |
Returns:
| Type | Description |
|---|---|
|
True if the object is an instance of class_name or its subclasses. |
Source code in src/momapy/styling.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 |
|---|---|---|
selectors |
tuple[Selector, ...]
|
Tuple of selectors, all of which must match. |
Example
selector = CompoundSelector((TypeSelector("Rectangle"), ClassSelector("Colored"))) selector.match(element) # True if element is Rectangle AND Colored
Methods:
| Name | Description |
|---|---|
select |
Check if all selectors in the tuple match. |
select
select(obj: LayoutElement | LayoutElementBuilder, ancestors: Collection[LayoutElement | LayoutElementBuilder])
Check if all selectors in the tuple match.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
obj
|
LayoutElement | LayoutElementBuilder
|
The layout element or builder to test. |
required |
ancestors
|
Collection[LayoutElement | LayoutElementBuilder]
|
List of ancestor elements. |
required |
Returns:
| Type | Description |
|---|---|
|
True if all selectors match the object. |
Source code in src/momapy/styling.py
DescendantSelector
dataclass
Bases: Selector
Selector that matches elements that are descendants of an ancestor.
Attributes:
| Name | Type | Description |
|---|---|---|
ancestor_selector |
Selector
|
The selector for any ancestor element. |
descendant_selector |
Selector
|
The selector for the descendant element. |
Example
selector = DescendantSelector(TypeSelector("Group"), TypeSelector("Text")) selector.match(text, [subgroup, group]) # True if text is somewhere inside group
Methods:
| Name | Description |
|---|---|
select |
Check if the object is a descendant matching the criteria. |
select
select(obj: LayoutElement | LayoutElementBuilder, ancestors: Collection[LayoutElement | LayoutElementBuilder])
Check if the object is a descendant matching the criteria.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
obj
|
LayoutElement | LayoutElementBuilder
|
The layout element or builder to test. |
required |
ancestors
|
Collection[LayoutElement | LayoutElementBuilder]
|
List of ancestor elements. |
required |
Returns:
| Type | Description |
|---|---|
|
True if the object matches descendant_selector and any ancestor |
|
|
matches ancestor_selector. |
Source code in src/momapy/styling.py
IdSelector
dataclass
Bases: Selector
Selector that matches elements by their id attribute.
Attributes:
| Name | Type | Description |
|---|---|---|
id_ |
str
|
The identifier to match. |
Example
selector = IdSelector("main_node") selector.match(element) # True if element.id_ == "main_node"
Methods:
| Name | Description |
|---|---|
select |
Check if the object has the specified id. |
select
select(obj: LayoutElement | LayoutElementBuilder, ancestors: Collection[LayoutElement | LayoutElementBuilder])
Check if the object has the specified id.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
obj
|
LayoutElement | LayoutElementBuilder
|
The layout element or builder to test. |
required |
ancestors
|
Collection[LayoutElement | LayoutElementBuilder]
|
List of ancestor elements (unused for id matching). |
required |
Returns:
| Type | Description |
|---|---|
|
True if the object has an id_ attribute matching the selector. |
Source code in src/momapy/styling.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 |
|---|---|---|
selectors |
tuple[Selector, ...]
|
Tuple of selectors, none of which should match. |
Example
selector = NotSelector((TypeSelector("Hidden"),)) selector.match(element) # True if element is NOT of type Hidden
Methods:
| Name | Description |
|---|---|
select |
Check if none of the selectors in the tuple match. |
select
select(obj: LayoutElement | LayoutElementBuilder, ancestors: Collection[LayoutElement | LayoutElementBuilder])
Check if none of the selectors in the tuple match.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
obj
|
LayoutElement | LayoutElementBuilder
|
The layout element or builder to test. |
required |
ancestors
|
Collection[LayoutElement | LayoutElementBuilder]
|
List of ancestor elements. |
required |
Returns:
| Type | Description |
|---|---|
|
True if no selector matches the object. |
Source code in src/momapy/styling.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 |
|---|---|---|
selectors |
tuple[Selector, ...]
|
Tuple of selectors, any of which can match. |
Example
selector = OrSelector((TypeSelector("Rectangle"), TypeSelector("Circle"))) selector.match(some_shape) # True if shape is Rectangle OR Circle
Methods:
| Name | Description |
|---|---|
select |
Check if any selector in the tuple matches. |
select
select(obj: LayoutElement | LayoutElementBuilder, ancestors: Collection[LayoutElement | LayoutElementBuilder])
Check if any selector in the tuple matches.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
obj
|
LayoutElement | LayoutElementBuilder
|
The layout element or builder to test. |
required |
ancestors
|
Collection[LayoutElement | LayoutElementBuilder]
|
List of ancestor elements. |
required |
Returns:
| Type | Description |
|---|---|
|
True if any selector matches the object. |
Source code in src/momapy/styling.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 | LayoutElementBuilder, ancestors: Collection[LayoutElement | LayoutElementBuilder]) -> bool
Check if the layout element matches this selector.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
obj
|
LayoutElement | LayoutElementBuilder
|
The layout element or builder to test. |
required |
ancestors
|
Collection[LayoutElement | LayoutElementBuilder]
|
List of ancestor elements. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if the element matches, False otherwise. |
Source code in src/momapy/styling.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.
Example
styles = StyleCollection({"fill": "red", "stroke_width": 2}) styles["fill"] 'red'
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.
Example
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) -> StyleSheet
Parse and return a StyleSheet from a CSS file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
file_path
|
str
|
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.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.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. |
Example
css = "Rectangle { fill: red; }" ss = StyleSheet.from_string(css)
Source code in src/momapy/styling.py
TypeSelector
dataclass
Bases: Selector
Selector that matches elements by their exact class name.
Attributes:
| Name | Type | Description |
|---|---|---|
class_name |
str
|
The exact class name to match (e.g., "Rectangle"). |
Example
selector = TypeSelector("Rectangle") selector.match(some_rectangle) # True if type is Rectangle
Methods:
| Name | Description |
|---|---|
select |
Check if the object's class name matches exactly. |
select
select(obj: LayoutElement | LayoutElementBuilder, ancestors: Collection[LayoutElement | LayoutElementBuilder])
Check if the object's class name matches exactly.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
obj
|
LayoutElement | LayoutElementBuilder
|
The layout element or builder to test. |
required |
ancestors
|
Collection[LayoutElement | LayoutElementBuilder]
|
List of ancestor elements (unused for type matching). |
required |
Returns:
| Type | Description |
|---|---|
|
True if the object's class name or builder name matches. |
Source code in src/momapy/styling.py
apply_style_collection
apply_style_collection(layout_element: LayoutElement | LayoutElementBuilder, style_collection: StyleCollection, strict: bool = True) -> LayoutElement | LayoutElementBuilder
Apply a StyleCollection to a layout element.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
layout_element
|
LayoutElement | LayoutElementBuilder
|
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 | LayoutElementBuilder
|
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.py
apply_style_sheet
apply_style_sheet(map_or_layout_element: Map | LayoutElement | MapBuilder | LayoutElementBuilder, style_sheet: StyleSheet, strict: bool = True, ancestors: Collection[LayoutElement | LayoutElementBuilder] = None) -> Map | LayoutElement | LayoutElementBuilder | MapBuilder
Apply a StyleSheet to a layout element or map layout recursively.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
map_or_layout_element
|
Map | LayoutElement | MapBuilder | LayoutElementBuilder
|
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 | LayoutElementBuilder]
|
Internal list of ancestor elements for selector matching. |
None
|
Returns:
| Type | Description |
|---|---|
Map | LayoutElement | LayoutElementBuilder | MapBuilder
|
The modified map, layout element, or builder. |
Source code in src/momapy/styling.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. |