Skip to main content

pptx_notes_and_comments/
pptx_notes_and_comments.rs

1//! PowerPoint speaker notes and reviewer comments. One slide per feature.
2//!
3//! Run with: `cargo run -p office-toolkit --example pptx_notes_and_comments`
4
5use std::path::{Path, PathBuf};
6
7use office_toolkit::SaveToFile;
8use office_toolkit::drawing::{ShapeProperties, TextBody, TextParagraph, TextRun, Transform2D};
9use office_toolkit::powerpoint::{AutoShape, Shape, SlideComment};
10use office_toolkit::prelude::*;
11
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}
67
68/// Every example in this directory writes its output under
69/// `tests-data/output/`, resolved relative to this crate's own manifest so
70/// it works no matter what directory `cargo run` was invoked from.
71fn output_path(filename: &str) -> PathBuf {
72    Path::new(env!("CARGO_MANIFEST_DIR"))
73        .join("../../tests-data/output")
74        .join(filename)
75}