0
# Styling System
1
2
Comprehensive styling framework providing CSS-like functionality with selectors, inheritance, attribute validation, and stylesheet management. The styling system enables fine-grained control over document appearance while maintaining consistency and maintainability.
3
4
## Capabilities
5
6
### Core Style Classes
7
8
Foundation classes for the styling system including Style objects, styled elements, and attribute management.
9
10
```python { .api }
11
class Style(AttributesDictionary):
12
"""
13
Style definition with validated attributes and inheritance.
14
15
Parameters:
16
- base: Style, optional base style to inherit from
17
- **attributes: style attribute key-value pairs
18
"""
19
def __init__(self, base=None, **attributes): ...
20
21
def copy(self): ... # Create deep copy
22
23
class Styled(DocumentElement):
24
"""
25
Base class for elements that can be styled.
26
27
Attributes:
28
- style: Style object or None for element styling
29
"""
30
style = Attribute(Style, None)
31
32
def get_style(self, attribute, flowable_target=None): ...
33
def get_config_value(self, attribute, document=None): ...
34
35
class StyledMeta(type):
36
"""Metaclass for styled elements providing style attribute registration."""
37
```
38
39
### StyleSheet Management
40
41
StyleSheet system for organizing and applying styles across documents with selector-based targeting.
42
43
```python { .api }
44
class StyleSheet(dict):
45
"""
46
Collection of styles with selectors for element targeting.
47
48
Parameters:
49
- name: str, stylesheet name
50
- base: StyleSheet, optional base stylesheet to inherit from
51
- matcher: StyledMatcher, custom matching system
52
"""
53
def __init__(self, name, base=None, matcher=None): ...
54
55
def __getitem__(self, styled_class): ... # Get style for element type
56
def __setitem__(self, selector, style): ... # Set style for selector
57
def match(self, styled, container): ... # Find matching style
58
59
class StyleSheetFile(StyleSheet):
60
"""
61
StyleSheet loaded from configuration file.
62
63
Parameters:
64
- file: str or file-like, path to or open file containing stylesheet
65
"""
66
def __init__(self, file): ...
67
```
68
69
### Selectors
70
71
CSS-like selectors for targeting specific elements and contexts within documents.
72
73
```python { .api }
74
class ClassSelector:
75
"""
76
Select elements by their class/type.
77
78
Parameters:
79
- styled_class: class to select
80
- style: Style to apply to matching elements
81
"""
82
def __init__(self, styled_class, style): ...
83
84
def match(self, styled, container): ... # Check if element matches
85
86
class ContextSelector:
87
"""
88
Select elements based on their context/ancestors.
89
90
Parameters:
91
- *selectors: sequence of parent selectors
92
- style: Style to apply to matching elements
93
"""
94
def __init__(self, *selectors, style): ...
95
96
# Predefined constants
97
PARENT_STYLE = ... # Reference to parent element's style
98
```
99
100
### Style Matching
101
102
Advanced style matching system for resolving styles based on element context and selectors.
103
104
```python { .api }
105
class StyledMatcher:
106
"""
107
System for matching elements to styles based on selectors.
108
109
Parameters:
110
- stylesheet: StyleSheet containing style rules
111
"""
112
def __init__(self, stylesheet): ...
113
114
def match(self, styled, container): ... # Find best matching style
115
def get_matches(self, styled, container): ... # Get all matching styles
116
```
117
118
### Attribute System
119
120
Type-safe attribute system with validation, defaults, and inheritance support.
121
122
```python { .api }
123
class AttributeType:
124
"""
125
Base class for style attribute types with validation.
126
127
Parameters:
128
- default_value: default value for this attribute type
129
"""
130
def __init__(self, default_value=None): ...
131
132
def __call__(self, value): ... # Validate and convert value
133
def __repr__(self): ...
134
135
class AcceptNoneAttributeType(AttributeType):
136
"""AttributeType that accepts None as a valid value."""
137
138
class Attribute:
139
"""
140
Descriptor for validated style attributes.
141
142
Parameters:
143
- attribute_type: AttributeType for validation
144
- default_value: default value (overrides type default)
145
- accepted_type: type or tuple of types for isinstance checking
146
"""
147
def __init__(self, attribute_type, default_value=None, accepted_type=None): ...
148
149
def __get__(self, instance, owner): ...
150
def __set__(self, instance, value): ...
151
152
class OverrideDefault:
153
"""Override default value in style inheritance."""
154
def __init__(self, value): ...
155
```
156
157
### Attribute Types
158
159
Predefined attribute types for common styling properties with validation and type conversion.
160
161
```python { .api }
162
class Bool(AttributeType):
163
"""
164
Boolean attribute type accepting 'true'/'false' strings.
165
"""
166
def __call__(self, value): ... # Convert to boolean
167
168
class Integer(AttributeType):
169
"""
170
Integer attribute type with validation.
171
172
Parameters:
173
- min_value: int, minimum allowed value
174
- max_value: int, maximum allowed value
175
"""
176
def __init__(self, min_value=None, max_value=None): ...
177
178
class OptionSet(AttributeType):
179
"""
180
Enumeration-like attribute type with predefined valid values.
181
182
Parameters:
183
- *values: allowed string values
184
"""
185
def __init__(self, *values): ...
186
187
class OptionSetMeta(type):
188
"""Metaclass for creating OptionSet classes."""
189
```
190
191
### Configuration System
192
193
Rule-based configuration system for complex styling scenarios and document settings.
194
195
```python { .api }
196
class Configurable:
197
"""
198
Base class for objects with configurable attributes.
199
200
Parameters:
201
- **configuration: configuration key-value pairs
202
"""
203
def __init__(self, **configuration): ...
204
205
def get_config_value(self, attribute, document=None): ...
206
207
class RuleSet(list):
208
"""
209
Collection of configuration rules with matching conditions.
210
211
Parameters:
212
- name: str, ruleset name
213
- base: RuleSet, optional base ruleset to inherit from
214
"""
215
def __init__(self, name, base=None): ...
216
217
def __getitem__(self, descriptor): ... # Get value for descriptor
218
def __setitem__(self, descriptor, value): ... # Set rule value
219
220
class RuleSetFile(RuleSet):
221
"""
222
RuleSet loaded from configuration file.
223
224
Parameters:
225
- file: str or file-like, path to or open file containing rules
226
"""
227
def __init__(self, file): ...
228
229
class Var:
230
"""
231
Variable reference in configuration files.
232
233
Parameters:
234
- name: str, variable name to reference
235
"""
236
def __init__(self, name): ...
237
```
238
239
### Dictionary System
240
241
Specialized dictionary classes for attribute management with validation and inheritance.
242
243
```python { .api }
244
class AttributesDictionary(dict):
245
"""
246
Dictionary with attribute validation and inheritance support.
247
248
Parameters:
249
- base_attributes: dict, base attributes to inherit from
250
- **attributes: additional attributes
251
"""
252
def __init__(self, base_attributes=None, **attributes): ...
253
254
def __getitem__(self, name): ... # Get attribute value
255
def __setitem__(self, name, value): ... # Set validated attribute
256
def copy(self): ... # Create deep copy
257
def update(self, other): ... # Update with validation
258
```
259
260
## Usage Examples
261
262
### Basic Styling
263
264
```python
265
from rinohtype.style import Style, StyleSheet
266
from rinohtype.color import Color
267
from rinohtype.dimension import PT
268
from rinohtype.paragraph import Paragraph, ParagraphStyle
269
270
# Create individual styles
271
heading_style = Style(
272
font_size=16*PT,
273
font_weight='bold',
274
text_color=Color(0, 0, 0.5),
275
space_above=12*PT,
276
space_below=6*PT
277
)
278
279
body_style = Style(
280
font_size=11*PT,
281
line_spacing=1.2,
282
text_align='justify',
283
space_below=6*PT
284
)
285
286
# Apply styles to elements
287
heading = Paragraph("Chapter Title", style=heading_style)
288
content = Paragraph("This is the body text...", style=body_style)
289
```
290
291
### StyleSheet Creation
292
293
```python
294
from rinohtype.style import StyleSheet, ClassSelector
295
from rinohtype.paragraph import ParagraphStyle
296
from rinohtype.structure import Heading
297
298
# Create stylesheet with selectors
299
stylesheet = StyleSheet('custom')
300
301
# Define styles for different element types
302
stylesheet[Paragraph] = ParagraphStyle(
303
font_family='serif',
304
font_size=11*PT,
305
line_spacing=1.2
306
)
307
308
stylesheet[Heading] = ParagraphStyle(
309
base=stylesheet[Paragraph], # Inherit from paragraph
310
font_size=16*PT,
311
font_weight='bold',
312
space_above=12*PT
313
)
314
315
# Context-sensitive styling
316
from rinohtype.style import ContextSelector
317
from rinohtype.structure import ListItem
318
319
stylesheet[ContextSelector(List, Paragraph)] = ParagraphStyle(
320
base=stylesheet[Paragraph],
321
space_below=3*PT # Less space in lists
322
)
323
```
324
325
### Custom Attribute Types
326
327
```python
328
from rinohtype.attribute import AttributeType, OptionSet
329
330
class FontWeight(OptionSet):
331
"""Font weight attribute type."""
332
values = ('normal', 'bold', '100', '200', '300', '400', '500', '600', '700', '800', '900')
333
334
class TextAlign(OptionSet):
335
"""Text alignment attribute type."""
336
values = ('left', 'center', 'right', 'justify')
337
338
# Use in style definitions
339
custom_style = Style(
340
font_weight=FontWeight('bold'),
341
text_align=TextAlign('center')
342
)
343
```
344
345
### Configuration Rules
346
347
```python
348
from rinohtype.attribute import RuleSet, Var
349
350
# Create configuration rules
351
config = RuleSet('document_config')
352
353
# Set variables
354
config['title_font_size'] = 18*PT
355
config['body_font_size'] = 11*PT
356
357
# Use variables in styles
358
title_style = Style(
359
font_size=Var('title_font_size'),
360
font_weight='bold'
361
)
362
363
# Conditional rules based on document properties
364
config[('paper_size', 'A4')] = {
365
'margin_left': 25*MM,
366
'margin_right': 25*MM
367
}
368
369
config[('paper_size', 'LETTER')] = {
370
'margin_left': 1*INCH,
371
'margin_right': 1*INCH
372
}
373
```
374
375
### Error Handling
376
377
```python
378
from rinohtype.attribute import ParseError
379
380
try:
381
# Invalid style attribute
382
invalid_style = Style(font_size='invalid')
383
except ParseError as e:
384
print(f"Style parsing error: {e}")
385
386
try:
387
# Load stylesheet from file
388
stylesheet = StyleSheetFile('styles.conf')
389
except (FileNotFoundError, ParseError) as e:
390
print(f"Stylesheet loading error: {e}")
391
```