Skip to main content

fop_layout/layout/properties/
break_keep.rs

1//! Break and keep property extraction
2
3use fop_core::{PropertyId, PropertyList};
4
5use super::types::{BreakValue, Keep, KeepConstraint};
6
7/// Extract keep constraints from properties
8///
9/// Extracts keep-together, keep-with-next, and keep-with-previous properties
10/// from a PropertyList and returns a KeepConstraint struct.
11///
12/// # Examples
13///
14/// ```
15/// use fop_core::{PropertyList, PropertyId, PropertyValue};
16/// use fop_layout::layout::extract_keep_constraint;
17/// use std::borrow::Cow;
18///
19/// let mut props = PropertyList::new();
20/// props.set(PropertyId::KeepTogether, PropertyValue::String(Cow::Borrowed("always")));
21///
22/// let constraint = extract_keep_constraint(&props);
23/// assert!(constraint.must_keep_together());
24/// ```
25pub fn extract_keep_constraint(properties: &PropertyList) -> KeepConstraint {
26    let mut constraint = KeepConstraint::new();
27
28    // Extract keep-together.within-page
29    if let Ok(value) = properties.get(PropertyId::KeepTogether) {
30        constraint.keep_together = Keep::from_property_value(&value);
31    }
32
33    // Extract keep-with-next.within-page
34    if let Ok(value) = properties.get(PropertyId::KeepWithNext) {
35        constraint.keep_with_next = Keep::from_property_value(&value);
36    }
37
38    // Extract keep-with-previous.within-page
39    if let Ok(value) = properties.get(PropertyId::KeepWithPrevious) {
40        constraint.keep_with_previous = Keep::from_property_value(&value);
41    }
42
43    constraint
44}
45
46/// Extract break-before property from properties
47///
48/// # Examples
49///
50/// ```
51/// use fop_core::{PropertyList, PropertyId, PropertyValue};
52/// use fop_layout::layout::extract_break_before;
53/// use std::borrow::Cow;
54///
55/// let mut props = PropertyList::new();
56/// props.set(PropertyId::BreakBefore, PropertyValue::String(Cow::Borrowed("page")));
57///
58/// let break_val = extract_break_before(&props);
59/// assert!(break_val.forces_break());
60/// ```
61pub fn extract_break_before(properties: &PropertyList) -> BreakValue {
62    properties
63        .get(PropertyId::BreakBefore)
64        .ok()
65        .map(|v| BreakValue::from_property_value(&v))
66        .unwrap_or(BreakValue::Auto)
67}
68
69/// Extract break-after property from properties
70///
71/// # Examples
72///
73/// ```
74/// use fop_core::{PropertyList, PropertyId, PropertyValue};
75/// use fop_layout::layout::extract_break_after;
76/// use std::borrow::Cow;
77///
78/// let mut props = PropertyList::new();
79/// props.set(PropertyId::BreakAfter, PropertyValue::String(Cow::Borrowed("page")));
80///
81/// let break_val = extract_break_after(&props);
82/// assert!(break_val.forces_break());
83/// ```
84pub fn extract_break_after(properties: &PropertyList) -> BreakValue {
85    properties
86        .get(PropertyId::BreakAfter)
87        .ok()
88        .map(|v| BreakValue::from_property_value(&v))
89        .unwrap_or(BreakValue::Auto)
90}
91
92/// Extract widows property from properties
93///
94/// Widows specifies the minimum number of lines that must be left at the
95/// top of a page when a paragraph is broken across pages. The default is 2.
96///
97/// # Examples
98///
99/// ```
100/// use fop_core::{PropertyList, PropertyId, PropertyValue};
101/// use fop_layout::layout::extract_widows;
102///
103/// let mut props = PropertyList::new();
104/// props.set(PropertyId::Widows, PropertyValue::Integer(3));
105///
106/// let widows = extract_widows(&props);
107/// assert_eq!(widows, 3);
108/// ```
109pub fn extract_widows(properties: &PropertyList) -> i32 {
110    properties
111        .get(PropertyId::Widows)
112        .ok()
113        .and_then(|v| v.as_integer())
114        .unwrap_or(2) // Default value per XSL-FO spec
115}
116
117/// Extract orphans property from properties
118///
119/// Orphans specifies the minimum number of lines that must be left at the
120/// bottom of a page when a paragraph is broken across pages. The default is 2.
121///
122/// # Examples
123///
124/// ```
125/// use fop_core::{PropertyList, PropertyId, PropertyValue};
126/// use fop_layout::layout::extract_orphans;
127///
128/// let mut props = PropertyList::new();
129/// props.set(PropertyId::Orphans, PropertyValue::Integer(3));
130///
131/// let orphans = extract_orphans(&props);
132/// assert_eq!(orphans, 3);
133/// ```
134pub fn extract_orphans(properties: &PropertyList) -> i32 {
135    properties
136        .get(PropertyId::Orphans)
137        .ok()
138        .and_then(|v| v.as_integer())
139        .unwrap_or(2) // Default value per XSL-FO spec
140}