pub struct TextParagraph {
pub properties: Option<TextParagraphProperties>,
pub runs: Vec<TextRun>,
}Expand description
One paragraph of text (<a:p>, CT_TextParagraph).
Not modeled: <a:endParaRPr> (the formatting a UI would apply to text typed at this paragraph’s
very end — a cosmetic authoring aid with no effect on existing content).
Fields§
§properties: Option<TextParagraphProperties><a:pPr>.
runs: Vec<TextRun>EG_TextRun — this crate only models the r/br choices (regular text and line breaks);
fld (a field, e.g. a slide-number placeholder) is deferred — see TextRun’s doc
comment.
Implementations§
Source§impl TextParagraph
impl TextParagraph
Sourcepub fn new() -> TextParagraph
pub fn new() -> TextParagraph
Examples found in repository?
More examples
examples/hello_world_pptx.rs (line 27)
14fn main() -> office_toolkit::Result<()> {
15 let path = output_path("hello_world.pptx");
16
17 let text_box = AutoShape::new(2, "Hello box")
18 .with_properties(
19 ShapeProperties::new().with_transform(
20 Transform2D::new()
21 .with_offset(838_200, 1_365_250)
22 .with_extent(7_772_400, 1_200_150),
23 ),
24 )
25 .with_text_body(
26 TextBody::new()
27 .with_paragraph(TextParagraph::new().with_run(TextRun::text("Hello, world!"))),
28 );
29
30 // `Presentation` and `Slide` both come from `office_toolkit::prelude`.
31 let presentation =
32 Presentation::new().with_slide(Slide::new().with_shape(Shape::AutoShape(text_box)));
33 presentation.save_to_file(&path)?;
34 println!("Wrote {}", path.display());
35
36 // Read the file back to confirm it is a valid .pptx.
37 let reopened = Presentation::open_file(&path)?;
38 println!("Slide count: {}", reopened.slides.len());
39
40 Ok(())
41}examples/pptx_notes_and_comments.rs (line 25)
12fn main() -> office_toolkit::Result<()> {
13 let path = output_path("pptx_notes_and_comments.pptx");
14
15 let title = |text: &str| {
16 AutoShape::new(2, "Title")
17 .with_properties(
18 ShapeProperties::new().with_transform(
19 Transform2D::new()
20 .with_offset(838_200, 838_200)
21 .with_extent(8_000_000, 1_000_000),
22 ),
23 )
24 .with_text_body(
25 TextBody::new().with_paragraph(TextParagraph::new().with_run(TextRun::text(text))),
26 )
27 };
28
29 let notes_slide = Slide::new()
30 .with_shape(Shape::AutoShape(title("A slide with speaker notes")))
31 .with_notes(
32 TextBody::new().with_paragraph(
33 TextParagraph::new()
34 .with_run(TextRun::text("Remember to mention the Q3 numbers here.")),
35 ),
36 );
37
38 let commented_slide = Slide::new()
39 .with_shape(Shape::AutoShape(title("A slide with reviewer comments")))
40 .with_comment(
41 SlideComment::new(
42 "Reviewer",
43 "RV",
44 "2026-07-21T10:00:00",
45 "This claim needs a source.",
46 )
47 .with_position(1_000_000, 2_000_000),
48 )
49 .with_comment(
50 SlideComment::new(
51 "Editor",
52 "ED",
53 "2026-07-21T11:30:00",
54 "Looks good otherwise.",
55 )
56 .with_position(3_000_000, 2_000_000),
57 );
58
59 let presentation = Presentation::new()
60 .with_slide(notes_slide)
61 .with_slide(commented_slide);
62
63 presentation.save_to_file(&path)?;
64 println!("Wrote {}", path.display());
65 Ok(())
66}examples/pptx_shapes_and_placeholders.rs (line 27)
14fn main() -> office_toolkit::Result<()> {
15 let path = output_path("pptx_shapes_and_placeholders.pptx");
16
17 let plain_shape = AutoShape::new(2, "Plain autoshape")
18 .with_properties(
19 ShapeProperties::new().with_transform(
20 Transform2D::new()
21 .with_offset(838_200, 838_200)
22 .with_extent(5_000_000, 1_000_000),
23 ),
24 )
25 .with_text_body(
26 TextBody::new()
27 .with_paragraph(TextParagraph::new().with_run(TextRun::text("A plain autoshape."))),
28 );
29
30 let text_box = AutoShape::new(2, "Text box")
31 .with_text_box(true)
32 .with_properties(
33 ShapeProperties::new().with_transform(
34 Transform2D::new()
35 .with_offset(838_200, 838_200)
36 .with_extent(5_000_000, 1_000_000),
37 ),
38 )
39 .with_text_body(TextBody::new().with_paragraph(
40 TextParagraph::new().with_run(TextRun::text("A genuine text box (txBox=\"1\").")),
41 ));
42
43 let title = AutoShape::new(2, "Title placeholder")
44 .with_placeholder(Placeholder::new(PlaceholderKind::CenterTitle))
45 .with_properties(
46 ShapeProperties::new().with_transform(
47 Transform2D::new()
48 .with_offset(838_200, 838_200)
49 .with_extent(10_515_600, 1_325_563),
50 ),
51 )
52 .with_text_body(
53 TextBody::new()
54 .with_paragraph(TextParagraph::new().with_run(TextRun::text("Title placeholder"))),
55 );
56 let subtitle =
57 AutoShape::new(3, "Subtitle placeholder")
58 .with_placeholder(Placeholder::new(PlaceholderKind::SubTitle).with_index(1))
59 .with_properties(
60 ShapeProperties::new().with_transform(
61 Transform2D::new()
62 .with_offset(838_200, 2_400_000)
63 .with_extent(10_515_600, 800_000),
64 ),
65 )
66 .with_text_body(TextBody::new().with_paragraph(
67 TextParagraph::new().with_run(TextRun::text("Subtitle placeholder")),
68 ));
69
70 let hyperlinked_shape = AutoShape::new(2, "Hyperlinked shape")
71 .with_hyperlink("https://www.rust-lang.org")
72 .with_properties(
73 ShapeProperties::new().with_transform(
74 Transform2D::new()
75 .with_offset(838_200, 838_200)
76 .with_extent(5_000_000, 1_000_000),
77 ),
78 )
79 .with_text_body(TextBody::new().with_paragraph(
80 TextParagraph::new().with_run(TextRun::text("Click this shape to open a link.")),
81 ));
82
83 let presentation = Presentation::new()
84 .with_slide(Slide::new().with_shape(Shape::AutoShape(plain_shape)))
85 .with_slide(Slide::new().with_shape(Shape::AutoShape(text_box)))
86 .with_slide(
87 Slide::new()
88 .with_shape(Shape::AutoShape(title))
89 .with_shape(Shape::AutoShape(subtitle)),
90 )
91 .with_slide(Slide::new().with_shape(Shape::AutoShape(hyperlinked_shape)));
92
93 presentation.save_to_file(&path)?;
94 println!("Wrote {}", path.display());
95 Ok(())
96}examples/pptx_theme_and_metadata.rs (line 69)
19fn main() -> office_toolkit::Result<()> {
20 // A custom theme and an embedded font. `Theme`/`ColorScheme`/
21 // `FontScheme` have no `with_*` builders in this crate — only
22 // `office_default()` or plain struct literals.
23 let custom_theme = Theme {
24 name: "Custom Brand".to_string(),
25 colors: ColorScheme {
26 dark1: "1B1B1B".to_string(),
27 light1: "FFFFFF".to_string(),
28 dark2: "0A2540".to_string(),
29 light2: "F5F5F5".to_string(),
30 accent1: "0A2540".to_string(),
31 accent2: "E8622C".to_string(),
32 accent3: "2E86AB".to_string(),
33 accent4: "6FB98F".to_string(),
34 accent5: "F4A259".to_string(),
35 accent6: "8E4585".to_string(),
36 hyperlink: "1155CC".to_string(),
37 followed_hyperlink: "6B3FA0".to_string(),
38 },
39 fonts: FontScheme {
40 major_latin: "Georgia".to_string(),
41 minor_latin: "Verdana".to_string(),
42 },
43 };
44
45 // Placeholder bytes — a real .pptx would carry genuine TrueType/
46 // OpenType font data here.
47 let embedded_font = EmbeddedFont::new("Custom Sans")
48 .with_regular(vec![0u8; 16])
49 .with_bold(vec![0u8; 16]);
50
51 // A slide with no shapes at all renders as a blank page — nothing shows
52 // the custom theme actually took effect. `drawing::Color` has no
53 // scheme-relative variant yet (`<a:schemeClr>` isn't modeled, see that
54 // enum's own doc comment), so this can't reference the theme's accent1
55 // symbolically; it uses the same literal hex values the theme itself
56 // was built from, purely so the slide visibly matches the palette above.
57 let title_shape = AutoShape::new(2, "Title")
58 .with_properties(
59 ShapeProperties::new()
60 .with_transform(
61 Transform2D::new()
62 .with_offset(838_200, 838_200)
63 .with_extent(6_000_000, 1_500_000),
64 )
65 .with_fill(Fill::Solid(Color::Rgb(custom_theme.colors.accent1.clone()))),
66 )
67 .with_text_body(
68 TextBody::new().with_paragraph(
69 TextParagraph::new().with_run(TextRun::text_with_properties(
70 "Custom Brand theme — Georgia / Verdana, accent1 = #0A2540",
71 TextRunProperties::new()
72 .with_font_family(custom_theme.fonts.major_latin.clone())
73 .with_font_size_points(24.0)
74 .with_fill(Fill::Solid(Color::Rgb(custom_theme.colors.light1.clone()))),
75 )),
76 ),
77 );
78
79 let themed_presentation = Presentation::new()
80 .with_theme(custom_theme)
81 .with_embedded_font(embedded_font)
82 .with_slide(Slide::new().with_shape(Shape::AutoShape(title_shape)));
83 let theme_path = output_path("pptx_theme.pptx");
84 themed_presentation.save_to_file(&theme_path)?;
85 println!("Wrote {}", theme_path.display());
86
87 // Document metadata (docProps/core.xml, app.xml, and custom.xml).
88 let properties = DocumentProperties::new()
89 .with_title("Metadata example")
90 .with_author("Example Author")
91 .with_subject("Presentation-level features")
92 .with_custom_property(
93 "ProjectCode",
94 CustomPropertyValue::Text("PPTX-META".to_string()),
95 );
96 // Same reasoning as `title_shape` above: an empty slide would render
97 // blank, so a text shape spells out where the metadata actually lives.
98 let metadata_shape = AutoShape::new(2, "Note")
99 .with_properties(ShapeProperties::new().with_transform(Transform2D::new().with_offset(838_200, 838_200).with_extent(7_000_000, 1_000_000)))
100 .with_text_body(TextBody::new().with_paragraph(TextParagraph::new().with_run(TextRun::text(
101 "This presentation's metadata is in File > Info (title, author, subject, and a custom \"ProjectCode\" property) — not on this slide.",
102 ))));
103 let metadata_presentation = Presentation::new()
104 .with_properties(properties)
105 .with_slide(Slide::new().with_shape(Shape::AutoShape(metadata_shape)));
106 let metadata_path = output_path("pptx_metadata.pptx");
107 metadata_presentation.save_to_file(&metadata_path)?;
108 println!("Wrote {}", metadata_path.display());
109
110 Ok(())
111}examples/pptx_grouping_and_connectors.rs (line 48)
16fn main() -> office_toolkit::Result<()> {
17 let path = output_path("pptx_grouping_and_connectors.pptx");
18
19 // Every shape below sets an explicit fill (and the connector an
20 // explicit line): with neither a fill/line nor a `<p:style>` theme
21 // reference, a shape has nothing to paint and renders as fully
22 // invisible — the slide then looks blank even though the shapes are
23 // there. `AutoShape`/`Connector` have no `<p:style>` support yet, so an
24 // explicit `Fill`/`Line` is the only way to make a shape actually show.
25 let circle_fill = || Fill::Solid(Color::Rgb("4472C4".to_string()));
26
27 let circle = AutoShape::new(11, "Circle").with_properties(
28 ShapeProperties::new()
29 .with_transform(
30 Transform2D::new()
31 .with_offset(0, 0)
32 .with_extent(1_000_000, 1_000_000),
33 )
34 .with_fill(circle_fill()),
35 );
36 let label = AutoShape::new(12, "Label")
37 .with_properties(
38 ShapeProperties::new()
39 .with_transform(
40 Transform2D::new()
41 .with_offset(1_200_000, 300_000)
42 .with_extent(1_500_000, 400_000),
43 )
44 .with_fill(Fill::Solid(Color::Rgb("E8622C".to_string()))),
45 )
46 .with_text_body(
47 TextBody::new()
48 .with_paragraph(TextParagraph::new().with_run(TextRun::text("Grouped label"))),
49 );
50
51 let group = ShapeGroup::new(2, "Group")
52 .with_transform(
53 (838_200, 838_200),
54 (2_700_000, 1_000_000),
55 (0, 0),
56 (2_700_000, 1_000_000),
57 )
58 .with_shape(Shape::AutoShape(circle))
59 .with_shape(Shape::AutoShape(label));
60
61 let rotated_circle = AutoShape::new(11, "Circle").with_properties(
62 ShapeProperties::new()
63 .with_transform(
64 Transform2D::new()
65 .with_offset(0, 0)
66 .with_extent(1_000_000, 1_000_000),
67 )
68 .with_fill(circle_fill()),
69 );
70 let rotated_group = ShapeGroup::new(2, "Rotated and flipped group")
71 .with_transform(
72 (838_200, 838_200),
73 (1_000_000, 1_000_000),
74 (0, 0),
75 (1_000_000, 1_000_000),
76 )
77 .with_rotation_degrees(45.0)
78 .with_flip_horizontal(true)
79 .with_shape(Shape::AutoShape(rotated_circle));
80
81 let box_a = AutoShape::new(2, "Box A").with_properties(
82 ShapeProperties::new()
83 .with_transform(
84 Transform2D::new()
85 .with_offset(838_200, 838_200)
86 .with_extent(1_000_000, 1_000_000),
87 )
88 .with_fill(Fill::Solid(Color::Rgb("2E86AB".to_string()))),
89 );
90 let box_b = AutoShape::new(3, "Box B").with_properties(
91 ShapeProperties::new()
92 .with_transform(
93 Transform2D::new()
94 .with_offset(3_500_000, 838_200)
95 .with_extent(1_000_000, 1_000_000),
96 )
97 .with_fill(Fill::Solid(Color::Rgb("6FB98F".to_string()))),
98 );
99 // `Connector::new` leaves position/size unset, which the writer then
100 // emits as a zero-size `<a:xfrm>` (off 0,0 / ext 0,0) — a real point
101 // with no length, invisible regardless of line/fill. `stCxn`/`endCxn`
102 // alone don't supply geometry; PowerPoint only recomputes it once you
103 // drag one of the attached shapes. So this also sets an explicit
104 // transform spanning Box A's right edge to Box B's left edge.
105 let connector = Connector::new(4, "Connector")
106 .with_properties(
107 ShapeProperties::new()
108 .with_transform(
109 Transform2D::new()
110 .with_offset(1_838_200, 1_338_200)
111 .with_extent(1_662_000, 0),
112 )
113 .with_line(
114 Line::new()
115 .with_width_emu(25_400)
116 .with_fill(Fill::Solid(Color::Rgb("000000".to_string()))),
117 ),
118 )
119 .with_start_connection(2, 0)
120 .with_end_connection(3, 0);
121
122 let presentation = Presentation::new()
123 .with_slide(Slide::new().with_shape(Shape::Group(group)))
124 .with_slide(Slide::new().with_shape(Shape::Group(rotated_group)))
125 .with_slide(
126 Slide::new()
127 .with_shape(Shape::AutoShape(box_a))
128 .with_shape(Shape::AutoShape(box_b))
129 .with_shape(Shape::Connector(connector)),
130 );
131
132 presentation.save_to_file(&path)?;
133 println!("Wrote {}", path.display());
134 Ok(())
135}Additional examples can be found in:
Sourcepub fn with_properties(
self,
properties: TextParagraphProperties,
) -> TextParagraph
pub fn with_properties( self, properties: TextParagraphProperties, ) -> TextParagraph
Examples found in repository?
examples/pptx_text_formatting.rs (lines 33-39)
19fn main() -> office_toolkit::Result<()> {
20 let path = output_path("pptx_text_formatting.pptx");
21
22 let spacing_shape = AutoShape::new(2, "Spacing")
23 .with_properties(
24 ShapeProperties::new().with_transform(
25 Transform2D::new()
26 .with_offset(838_200, 838_200)
27 .with_extent(6_000_000, 1_500_000),
28 ),
29 )
30 .with_text_body(
31 TextBody::new().with_paragraph(
32 TextParagraph::new()
33 .with_properties(
34 TextParagraphProperties::new()
35 .with_line_spacing(TextSpacing::Percent(150_000))
36 .with_space_before(TextSpacing::Points(1200))
37 .with_indent_emu(457_200)
38 .with_level(1),
39 )
40 .with_run(TextRun::text(
41 "Indented, 150% line spacing, 12pt space before.",
42 )),
43 ),
44 );
45
46 let bullets_shape = AutoShape::new(2, "Bullets")
47 .with_properties(
48 ShapeProperties::new().with_transform(
49 Transform2D::new()
50 .with_offset(838_200, 838_200)
51 .with_extent(6_000_000, 1_800_000),
52 ),
53 )
54 .with_text_body(
55 TextBody::new()
56 .with_paragraph(
57 TextParagraph::new()
58 .with_properties(
59 TextParagraphProperties::new()
60 .with_bullet(BulletKind::Character("\u{2022}".to_string())),
61 )
62 .with_run(TextRun::text("Bulleted item")),
63 )
64 .with_paragraph(
65 TextParagraph::new()
66 .with_properties(TextParagraphProperties::new().with_bullet(
67 BulletKind::AutoNumber {
68 scheme: "arabicPeriod".to_string(),
69 start_at: None,
70 },
71 ))
72 .with_run(TextRun::text("Auto-numbered item")),
73 ),
74 );
75
76 let autofit_shape = AutoShape::new(2, "Autofit")
77 .with_text_box(true)
78 .with_properties(
79 ShapeProperties::new().with_transform(
80 Transform2D::new()
81 .with_offset(838_200, 838_200)
82 .with_extent(4_000_000, 1_000_000),
83 ),
84 )
85 .with_text_body(
86 TextBody::new()
87 .with_properties(
88 TextBodyProperties::new()
89 .with_autofit(TextAutofit::Shape)
90 .with_anchor(TextAnchor::Center)
91 .with_anchor_center(true),
92 )
93 .with_paragraph(TextParagraph::new().with_run(TextRun::text(
94 "This shape resizes to fit its text, centered both ways.",
95 ))),
96 );
97
98 let casing_shape = AutoShape::new(2, "Casing")
99 .with_properties(
100 ShapeProperties::new().with_transform(
101 Transform2D::new()
102 .with_offset(838_200, 838_200)
103 .with_extent(6_000_000, 1_500_000),
104 ),
105 )
106 .with_text_body(
107 TextBody::new().with_paragraph(
108 TextParagraph::new()
109 .with_run(TextRun::text_with_properties(
110 "rendered in all caps, ",
111 TextRunProperties::new().with_text_caps(TextCaps::All),
112 ))
113 .with_run(TextRun::text_with_properties(
114 "widely spaced, ",
115 TextRunProperties::new().with_character_spacing_points(3.0),
116 ))
117 .with_run(TextRun::text_with_properties(
118 "highlighted",
119 TextRunProperties::new().with_highlight(Color::Rgb("FFFF00".to_string())),
120 ))
121 .with_run(TextRun::text_with_properties(
122 "2",
123 TextRunProperties::new().with_baseline_percent(30.0),
124 )),
125 ),
126 );
127
128 let field_shape = AutoShape::new(2, "Field")
129 .with_properties(
130 ShapeProperties::new().with_transform(
131 Transform2D::new()
132 .with_offset(838_200, 838_200)
133 .with_extent(3_000_000, 500_000),
134 ),
135 )
136 .with_text_body(
137 TextBody::new().with_paragraph(
138 TextParagraph::new()
139 .with_run(TextRun::text("Slide "))
140 .with_run(TextRun::field(
141 "{7A9E3F10-4B6C-4D2E-9A1F-8C5D6E7F0123}",
142 Some("slidenum".to_string()),
143 "1",
144 )),
145 ),
146 );
147
148 let presentation = Presentation::new()
149 .with_slide(Slide::new().with_shape(Shape::AutoShape(spacing_shape)))
150 .with_slide(Slide::new().with_shape(Shape::AutoShape(bullets_shape)))
151 .with_slide(Slide::new().with_shape(Shape::AutoShape(autofit_shape)))
152 .with_slide(Slide::new().with_shape(Shape::AutoShape(casing_shape)))
153 .with_slide(Slide::new().with_shape(Shape::AutoShape(field_shape)));
154
155 presentation.save_to_file(&path)?;
156 println!("Wrote {}", path.display());
157 Ok(())
158}Sourcepub fn with_run(self, run: TextRun) -> TextParagraph
pub fn with_run(self, run: TextRun) -> TextParagraph
Examples found in repository?
More examples
examples/hello_world_pptx.rs (line 27)
14fn main() -> office_toolkit::Result<()> {
15 let path = output_path("hello_world.pptx");
16
17 let text_box = AutoShape::new(2, "Hello box")
18 .with_properties(
19 ShapeProperties::new().with_transform(
20 Transform2D::new()
21 .with_offset(838_200, 1_365_250)
22 .with_extent(7_772_400, 1_200_150),
23 ),
24 )
25 .with_text_body(
26 TextBody::new()
27 .with_paragraph(TextParagraph::new().with_run(TextRun::text("Hello, world!"))),
28 );
29
30 // `Presentation` and `Slide` both come from `office_toolkit::prelude`.
31 let presentation =
32 Presentation::new().with_slide(Slide::new().with_shape(Shape::AutoShape(text_box)));
33 presentation.save_to_file(&path)?;
34 println!("Wrote {}", path.display());
35
36 // Read the file back to confirm it is a valid .pptx.
37 let reopened = Presentation::open_file(&path)?;
38 println!("Slide count: {}", reopened.slides.len());
39
40 Ok(())
41}examples/pptx_notes_and_comments.rs (line 25)
12fn main() -> office_toolkit::Result<()> {
13 let path = output_path("pptx_notes_and_comments.pptx");
14
15 let title = |text: &str| {
16 AutoShape::new(2, "Title")
17 .with_properties(
18 ShapeProperties::new().with_transform(
19 Transform2D::new()
20 .with_offset(838_200, 838_200)
21 .with_extent(8_000_000, 1_000_000),
22 ),
23 )
24 .with_text_body(
25 TextBody::new().with_paragraph(TextParagraph::new().with_run(TextRun::text(text))),
26 )
27 };
28
29 let notes_slide = Slide::new()
30 .with_shape(Shape::AutoShape(title("A slide with speaker notes")))
31 .with_notes(
32 TextBody::new().with_paragraph(
33 TextParagraph::new()
34 .with_run(TextRun::text("Remember to mention the Q3 numbers here.")),
35 ),
36 );
37
38 let commented_slide = Slide::new()
39 .with_shape(Shape::AutoShape(title("A slide with reviewer comments")))
40 .with_comment(
41 SlideComment::new(
42 "Reviewer",
43 "RV",
44 "2026-07-21T10:00:00",
45 "This claim needs a source.",
46 )
47 .with_position(1_000_000, 2_000_000),
48 )
49 .with_comment(
50 SlideComment::new(
51 "Editor",
52 "ED",
53 "2026-07-21T11:30:00",
54 "Looks good otherwise.",
55 )
56 .with_position(3_000_000, 2_000_000),
57 );
58
59 let presentation = Presentation::new()
60 .with_slide(notes_slide)
61 .with_slide(commented_slide);
62
63 presentation.save_to_file(&path)?;
64 println!("Wrote {}", path.display());
65 Ok(())
66}examples/pptx_shapes_and_placeholders.rs (line 27)
14fn main() -> office_toolkit::Result<()> {
15 let path = output_path("pptx_shapes_and_placeholders.pptx");
16
17 let plain_shape = AutoShape::new(2, "Plain autoshape")
18 .with_properties(
19 ShapeProperties::new().with_transform(
20 Transform2D::new()
21 .with_offset(838_200, 838_200)
22 .with_extent(5_000_000, 1_000_000),
23 ),
24 )
25 .with_text_body(
26 TextBody::new()
27 .with_paragraph(TextParagraph::new().with_run(TextRun::text("A plain autoshape."))),
28 );
29
30 let text_box = AutoShape::new(2, "Text box")
31 .with_text_box(true)
32 .with_properties(
33 ShapeProperties::new().with_transform(
34 Transform2D::new()
35 .with_offset(838_200, 838_200)
36 .with_extent(5_000_000, 1_000_000),
37 ),
38 )
39 .with_text_body(TextBody::new().with_paragraph(
40 TextParagraph::new().with_run(TextRun::text("A genuine text box (txBox=\"1\").")),
41 ));
42
43 let title = AutoShape::new(2, "Title placeholder")
44 .with_placeholder(Placeholder::new(PlaceholderKind::CenterTitle))
45 .with_properties(
46 ShapeProperties::new().with_transform(
47 Transform2D::new()
48 .with_offset(838_200, 838_200)
49 .with_extent(10_515_600, 1_325_563),
50 ),
51 )
52 .with_text_body(
53 TextBody::new()
54 .with_paragraph(TextParagraph::new().with_run(TextRun::text("Title placeholder"))),
55 );
56 let subtitle =
57 AutoShape::new(3, "Subtitle placeholder")
58 .with_placeholder(Placeholder::new(PlaceholderKind::SubTitle).with_index(1))
59 .with_properties(
60 ShapeProperties::new().with_transform(
61 Transform2D::new()
62 .with_offset(838_200, 2_400_000)
63 .with_extent(10_515_600, 800_000),
64 ),
65 )
66 .with_text_body(TextBody::new().with_paragraph(
67 TextParagraph::new().with_run(TextRun::text("Subtitle placeholder")),
68 ));
69
70 let hyperlinked_shape = AutoShape::new(2, "Hyperlinked shape")
71 .with_hyperlink("https://www.rust-lang.org")
72 .with_properties(
73 ShapeProperties::new().with_transform(
74 Transform2D::new()
75 .with_offset(838_200, 838_200)
76 .with_extent(5_000_000, 1_000_000),
77 ),
78 )
79 .with_text_body(TextBody::new().with_paragraph(
80 TextParagraph::new().with_run(TextRun::text("Click this shape to open a link.")),
81 ));
82
83 let presentation = Presentation::new()
84 .with_slide(Slide::new().with_shape(Shape::AutoShape(plain_shape)))
85 .with_slide(Slide::new().with_shape(Shape::AutoShape(text_box)))
86 .with_slide(
87 Slide::new()
88 .with_shape(Shape::AutoShape(title))
89 .with_shape(Shape::AutoShape(subtitle)),
90 )
91 .with_slide(Slide::new().with_shape(Shape::AutoShape(hyperlinked_shape)));
92
93 presentation.save_to_file(&path)?;
94 println!("Wrote {}", path.display());
95 Ok(())
96}examples/pptx_theme_and_metadata.rs (lines 69-75)
19fn main() -> office_toolkit::Result<()> {
20 // A custom theme and an embedded font. `Theme`/`ColorScheme`/
21 // `FontScheme` have no `with_*` builders in this crate — only
22 // `office_default()` or plain struct literals.
23 let custom_theme = Theme {
24 name: "Custom Brand".to_string(),
25 colors: ColorScheme {
26 dark1: "1B1B1B".to_string(),
27 light1: "FFFFFF".to_string(),
28 dark2: "0A2540".to_string(),
29 light2: "F5F5F5".to_string(),
30 accent1: "0A2540".to_string(),
31 accent2: "E8622C".to_string(),
32 accent3: "2E86AB".to_string(),
33 accent4: "6FB98F".to_string(),
34 accent5: "F4A259".to_string(),
35 accent6: "8E4585".to_string(),
36 hyperlink: "1155CC".to_string(),
37 followed_hyperlink: "6B3FA0".to_string(),
38 },
39 fonts: FontScheme {
40 major_latin: "Georgia".to_string(),
41 minor_latin: "Verdana".to_string(),
42 },
43 };
44
45 // Placeholder bytes — a real .pptx would carry genuine TrueType/
46 // OpenType font data here.
47 let embedded_font = EmbeddedFont::new("Custom Sans")
48 .with_regular(vec![0u8; 16])
49 .with_bold(vec![0u8; 16]);
50
51 // A slide with no shapes at all renders as a blank page — nothing shows
52 // the custom theme actually took effect. `drawing::Color` has no
53 // scheme-relative variant yet (`<a:schemeClr>` isn't modeled, see that
54 // enum's own doc comment), so this can't reference the theme's accent1
55 // symbolically; it uses the same literal hex values the theme itself
56 // was built from, purely so the slide visibly matches the palette above.
57 let title_shape = AutoShape::new(2, "Title")
58 .with_properties(
59 ShapeProperties::new()
60 .with_transform(
61 Transform2D::new()
62 .with_offset(838_200, 838_200)
63 .with_extent(6_000_000, 1_500_000),
64 )
65 .with_fill(Fill::Solid(Color::Rgb(custom_theme.colors.accent1.clone()))),
66 )
67 .with_text_body(
68 TextBody::new().with_paragraph(
69 TextParagraph::new().with_run(TextRun::text_with_properties(
70 "Custom Brand theme — Georgia / Verdana, accent1 = #0A2540",
71 TextRunProperties::new()
72 .with_font_family(custom_theme.fonts.major_latin.clone())
73 .with_font_size_points(24.0)
74 .with_fill(Fill::Solid(Color::Rgb(custom_theme.colors.light1.clone()))),
75 )),
76 ),
77 );
78
79 let themed_presentation = Presentation::new()
80 .with_theme(custom_theme)
81 .with_embedded_font(embedded_font)
82 .with_slide(Slide::new().with_shape(Shape::AutoShape(title_shape)));
83 let theme_path = output_path("pptx_theme.pptx");
84 themed_presentation.save_to_file(&theme_path)?;
85 println!("Wrote {}", theme_path.display());
86
87 // Document metadata (docProps/core.xml, app.xml, and custom.xml).
88 let properties = DocumentProperties::new()
89 .with_title("Metadata example")
90 .with_author("Example Author")
91 .with_subject("Presentation-level features")
92 .with_custom_property(
93 "ProjectCode",
94 CustomPropertyValue::Text("PPTX-META".to_string()),
95 );
96 // Same reasoning as `title_shape` above: an empty slide would render
97 // blank, so a text shape spells out where the metadata actually lives.
98 let metadata_shape = AutoShape::new(2, "Note")
99 .with_properties(ShapeProperties::new().with_transform(Transform2D::new().with_offset(838_200, 838_200).with_extent(7_000_000, 1_000_000)))
100 .with_text_body(TextBody::new().with_paragraph(TextParagraph::new().with_run(TextRun::text(
101 "This presentation's metadata is in File > Info (title, author, subject, and a custom \"ProjectCode\" property) — not on this slide.",
102 ))));
103 let metadata_presentation = Presentation::new()
104 .with_properties(properties)
105 .with_slide(Slide::new().with_shape(Shape::AutoShape(metadata_shape)));
106 let metadata_path = output_path("pptx_metadata.pptx");
107 metadata_presentation.save_to_file(&metadata_path)?;
108 println!("Wrote {}", metadata_path.display());
109
110 Ok(())
111}examples/pptx_grouping_and_connectors.rs (line 48)
16fn main() -> office_toolkit::Result<()> {
17 let path = output_path("pptx_grouping_and_connectors.pptx");
18
19 // Every shape below sets an explicit fill (and the connector an
20 // explicit line): with neither a fill/line nor a `<p:style>` theme
21 // reference, a shape has nothing to paint and renders as fully
22 // invisible — the slide then looks blank even though the shapes are
23 // there. `AutoShape`/`Connector` have no `<p:style>` support yet, so an
24 // explicit `Fill`/`Line` is the only way to make a shape actually show.
25 let circle_fill = || Fill::Solid(Color::Rgb("4472C4".to_string()));
26
27 let circle = AutoShape::new(11, "Circle").with_properties(
28 ShapeProperties::new()
29 .with_transform(
30 Transform2D::new()
31 .with_offset(0, 0)
32 .with_extent(1_000_000, 1_000_000),
33 )
34 .with_fill(circle_fill()),
35 );
36 let label = AutoShape::new(12, "Label")
37 .with_properties(
38 ShapeProperties::new()
39 .with_transform(
40 Transform2D::new()
41 .with_offset(1_200_000, 300_000)
42 .with_extent(1_500_000, 400_000),
43 )
44 .with_fill(Fill::Solid(Color::Rgb("E8622C".to_string()))),
45 )
46 .with_text_body(
47 TextBody::new()
48 .with_paragraph(TextParagraph::new().with_run(TextRun::text("Grouped label"))),
49 );
50
51 let group = ShapeGroup::new(2, "Group")
52 .with_transform(
53 (838_200, 838_200),
54 (2_700_000, 1_000_000),
55 (0, 0),
56 (2_700_000, 1_000_000),
57 )
58 .with_shape(Shape::AutoShape(circle))
59 .with_shape(Shape::AutoShape(label));
60
61 let rotated_circle = AutoShape::new(11, "Circle").with_properties(
62 ShapeProperties::new()
63 .with_transform(
64 Transform2D::new()
65 .with_offset(0, 0)
66 .with_extent(1_000_000, 1_000_000),
67 )
68 .with_fill(circle_fill()),
69 );
70 let rotated_group = ShapeGroup::new(2, "Rotated and flipped group")
71 .with_transform(
72 (838_200, 838_200),
73 (1_000_000, 1_000_000),
74 (0, 0),
75 (1_000_000, 1_000_000),
76 )
77 .with_rotation_degrees(45.0)
78 .with_flip_horizontal(true)
79 .with_shape(Shape::AutoShape(rotated_circle));
80
81 let box_a = AutoShape::new(2, "Box A").with_properties(
82 ShapeProperties::new()
83 .with_transform(
84 Transform2D::new()
85 .with_offset(838_200, 838_200)
86 .with_extent(1_000_000, 1_000_000),
87 )
88 .with_fill(Fill::Solid(Color::Rgb("2E86AB".to_string()))),
89 );
90 let box_b = AutoShape::new(3, "Box B").with_properties(
91 ShapeProperties::new()
92 .with_transform(
93 Transform2D::new()
94 .with_offset(3_500_000, 838_200)
95 .with_extent(1_000_000, 1_000_000),
96 )
97 .with_fill(Fill::Solid(Color::Rgb("6FB98F".to_string()))),
98 );
99 // `Connector::new` leaves position/size unset, which the writer then
100 // emits as a zero-size `<a:xfrm>` (off 0,0 / ext 0,0) — a real point
101 // with no length, invisible regardless of line/fill. `stCxn`/`endCxn`
102 // alone don't supply geometry; PowerPoint only recomputes it once you
103 // drag one of the attached shapes. So this also sets an explicit
104 // transform spanning Box A's right edge to Box B's left edge.
105 let connector = Connector::new(4, "Connector")
106 .with_properties(
107 ShapeProperties::new()
108 .with_transform(
109 Transform2D::new()
110 .with_offset(1_838_200, 1_338_200)
111 .with_extent(1_662_000, 0),
112 )
113 .with_line(
114 Line::new()
115 .with_width_emu(25_400)
116 .with_fill(Fill::Solid(Color::Rgb("000000".to_string()))),
117 ),
118 )
119 .with_start_connection(2, 0)
120 .with_end_connection(3, 0);
121
122 let presentation = Presentation::new()
123 .with_slide(Slide::new().with_shape(Shape::Group(group)))
124 .with_slide(Slide::new().with_shape(Shape::Group(rotated_group)))
125 .with_slide(
126 Slide::new()
127 .with_shape(Shape::AutoShape(box_a))
128 .with_shape(Shape::AutoShape(box_b))
129 .with_shape(Shape::Connector(connector)),
130 );
131
132 presentation.save_to_file(&path)?;
133 println!("Wrote {}", path.display());
134 Ok(())
135}Additional examples can be found in:
Trait Implementations§
Source§impl Clone for TextParagraph
impl Clone for TextParagraph
Source§fn clone(&self) -> TextParagraph
fn clone(&self) -> TextParagraph
Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
Performs copy-assignment from
source. Read moreSource§impl Debug for TextParagraph
impl Debug for TextParagraph
Source§impl Default for TextParagraph
impl Default for TextParagraph
Source§fn default() -> TextParagraph
fn default() -> TextParagraph
Returns the “default value” for a type. Read more
Source§impl PartialEq for TextParagraph
impl PartialEq for TextParagraph
impl StructuralPartialEq for TextParagraph
Auto Trait Implementations§
impl Freeze for TextParagraph
impl RefUnwindSafe for TextParagraph
impl Send for TextParagraph
impl Sync for TextParagraph
impl Unpin for TextParagraph
impl UnsafeUnpin for TextParagraph
impl UnwindSafe for TextParagraph
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more