ppt_rs/generator/text/
frame.rs1use super::paragraph::Paragraph;
4use super::TextAnchor;
5use crate::core::ToXml;
6
7#[derive(Clone, Debug)]
9pub struct TextFrame {
10 pub paragraphs: Vec<Paragraph>,
11 pub anchor: TextAnchor,
12 pub wrap: bool,
13 pub margin_left: u32,
14 pub margin_right: u32,
15 pub margin_top: u32,
16 pub margin_bottom: u32,
17}
18
19impl TextFrame {
20 pub fn new() -> Self {
22 TextFrame {
23 paragraphs: Vec::new(),
24 anchor: TextAnchor::Top,
25 wrap: true,
26 margin_left: 91440, margin_right: 91440,
28 margin_top: 45720, margin_bottom: 45720,
30 }
31 }
32
33 pub fn with_text(text: &str) -> Self {
35 let mut tf = Self::new();
36 tf.paragraphs.push(Paragraph::with_text(text));
37 tf
38 }
39
40 pub fn add_paragraph(mut self, para: Paragraph) -> Self {
42 self.paragraphs.push(para);
43 self
44 }
45
46 pub fn add_text(mut self, text: &str) -> Self {
48 self.paragraphs.push(Paragraph::with_text(text));
49 self
50 }
51
52 pub fn anchor(mut self, anchor: TextAnchor) -> Self {
54 self.anchor = anchor;
55 self
56 }
57
58 pub fn margins(mut self, left: u32, right: u32, top: u32, bottom: u32) -> Self {
60 self.margin_left = left;
61 self.margin_right = right;
62 self.margin_top = top;
63 self.margin_bottom = bottom;
64 self
65 }
66
67 pub fn to_xml(&self) -> String {
69 let wrap = if self.wrap { "square" } else { "none" };
70
71 let mut xml = format!(
72 r#"<p:txBody><a:bodyPr wrap="{}" lIns="{}" rIns="{}" tIns="{}" bIns="{}" anchor="{}"/><a:lstStyle/>"#,
73 wrap, self.margin_left, self.margin_right, self.margin_top, self.margin_bottom, self.anchor.to_xml()
74 );
75
76 for para in &self.paragraphs {
77 xml.push_str(¶.to_xml());
78 }
79
80 if self.paragraphs.is_empty() {
82 xml.push_str("<a:p/>");
83 }
84
85 xml.push_str("</p:txBody>");
86 xml
87 }
88}
89
90impl ToXml for TextFrame {
91 fn to_xml(&self) -> String {
92 TextFrame::to_xml(self)
93 }
94}
95
96impl Default for TextFrame {
97 fn default() -> Self {
98 Self::new()
99 }
100}
101
102#[cfg(test)]
103mod tests {
104 use super::*;
105 use crate::generator::text::TextAlign;
106
107 #[test]
108 fn test_text_frame_to_xml() {
109 let tf = TextFrame::new()
110 .add_paragraph(Paragraph::with_text("Title").align(TextAlign::Center))
111 .add_paragraph(Paragraph::with_text("Content"))
112 .anchor(TextAnchor::Middle);
113
114 let xml = tf.to_xml();
115
116 assert!(xml.contains("<p:txBody>"));
117 assert!(xml.contains("anchor=\"ctr\""));
118 assert!(xml.contains("Title"));
119 assert!(xml.contains("Content"));
120 }
121}