Skip to main content

pptx_to_md/
parser_config.rs

1use std::path::PathBuf;
2
3/// Determines how images are handled during content export.
4///
5/// # Members
6///
7/// | Member                | Description                                                                                                                       |
8/// |-----------------------|-----------------------------------------------------------------------------------------------------------------------------------|            
9/// | `InMarkdown`          | Images are embedded directly in the Markdown output using standard syntax as `base64` data (`![]()`)                              |            
10/// | `Manually`            | Image handling is delegated to the user, requiring manual copying or referencing (as `base64` encoded string)                     |            
11/// | `Save`                | Images are saved in a provided output directory and referenced using Markdown image syntax with a `file://` URL                  |
12#[derive(Debug, Clone, PartialEq, Eq)]
13pub enum ImageHandlingMode {
14    InMarkdown,
15    Manually,
16    Save,
17}
18
19/// Configuration options for the PPTX parser.
20///
21/// Use [`ParserConfig::builder()`] to create a configuration instance.
22/// This allows you to customize only the desired fields while falling back to sensible defaults for the rest.
23///
24/// # Configuration Options
25///
26/// | Parameter                 | Type                  | Default       | Description                                                                                               |
27/// |---------------------------|-----------------------|---------------|-----------------------------------------------------------------------------------------------------------|
28/// | `extract_images`          | `bool`                | `true`        | Whether images are extracted from slides or not. If false, images can not be extracted manually either    |
29/// | `compress_images`         | `bool`                | `true`        | Whether images are compressed before encoding or not. Effects manually extracted images too               |
30/// | `quality`                 | `u8`                  | `80`          | Compression level (0-100);<br/> higher values retain more detail but increase file size                   |
31/// | `image_handling_mode`     | `ImageHandlingMode`   | `InMarkdown`  | Determines how images are handled during content export                                                   |
32/// | `image_output_path`       | `Option<PathBuf>`     | `None`        | Output directory path for `ImageHandlingMode::Save` (mandatory for the saving mode)                       |
33/// | `include_slide_number_as_comment`   | `bool`                | `true`        | Whether the slide number comment is included (`<!-- Slide [n] -->`)                                       |
34/// | `include_speaker_notes`   | `bool`                | `false`       | Whether speaker notes are appended to Markdown as blockquotes                                               |
35/// | `include_comments`        | `bool`                | `false`       | Whether presentation comments are appended to Markdown as blockquotes                                       |
36/// | `include_presentation_metadata` | `bool`          | `true`        | Whether presentation-wide Markdown starts with a metadata comment                                            |
37///
38/// # Example
39///
40/// ```
41/// use std::path::PathBuf;
42/// use pptx_to_md::{ImageHandlingMode, ParserConfig};
43///
44/// let config = ParserConfig::builder()
45///     .extract_images(true)
46///     .compress_images(true)
47///     .quality(75)
48///     .image_handling_mode(ImageHandlingMode::Save)
49///     .image_output_path(PathBuf::from("/path/to/output/dir/"))
50///     .build();
51/// ```
52#[derive(Debug, Clone)]
53pub struct ParserConfig {
54    pub extract_images: bool,
55    pub compress_images: bool,
56    pub quality: u8,
57    pub image_handling_mode: ImageHandlingMode,
58    pub image_output_path: Option<PathBuf>,
59    pub include_slide_number_as_comment: bool,
60    pub include_speaker_notes: bool,
61    pub include_comments: bool,
62    pub include_presentation_metadata: bool,
63}
64
65impl Default for ParserConfig {
66    fn default() -> Self {
67        Self {
68            extract_images: true,
69            compress_images: true,
70            quality: 80,
71            image_handling_mode: ImageHandlingMode::InMarkdown,
72            image_output_path: None,
73            include_slide_number_as_comment: true,
74            include_speaker_notes: false,
75            include_comments: false,
76            include_presentation_metadata: true,
77        }
78    }
79}
80
81impl ParserConfig {
82    pub fn builder() -> ParserConfigBuilder {
83        ParserConfigBuilder::default()
84    }
85}
86
87/// Builder for [`ParserConfig`].
88///
89/// Allows setting individual configuration fields while falling back to defaults for any unspecified values
90#[derive(Debug, Default)]
91pub struct ParserConfigBuilder {
92    extract_images: Option<bool>,
93    compress_images: Option<bool>,
94    image_quality: Option<u8>,
95    image_handling_mode: Option<ImageHandlingMode>,
96    image_output_path: Option<PathBuf>,
97    include_slide_number_as_comment: Option<bool>,
98    include_speaker_notes: Option<bool>,
99    include_comments: Option<bool>,
100    include_presentation_metadata: Option<bool>,
101}
102
103impl ParserConfigBuilder {
104    /// Sets weather images should be extracted from the slides.
105    pub fn extract_images(mut self, value: bool) -> Self {
106        self.extract_images = Some(value);
107        self
108    }
109
110    /// Sets weather images should be compressed before encoded to base64 or not
111    pub fn compress_images(mut self, value: bool) -> Self {
112        self.compress_images = Some(value);
113        self
114    }
115
116    /// Specifies the desired image quality where `100` is the original quality and `50` means half the quality
117    /// The lower the quality, the smaller the file size of the output image will be
118    pub fn quality(mut self, value: u8) -> Self {
119        self.image_quality = Some(value);
120        self
121    }
122
123    /// Specifies the mode for processing the image after its extracted
124    pub fn image_handling_mode(mut self, value: ImageHandlingMode) -> Self {
125        self.image_handling_mode = Some(value);
126        self
127    }
128
129    /// Specifies the output directory for the [`ImageHandlingMode::Save`]
130    pub fn image_output_path<P>(mut self, path: P) -> Self
131    where
132        P: Into<PathBuf>,
133    {
134        self.image_output_path = Some(path.into());
135        self
136    }
137
138    /// Sets weather comments with the current slide number are included or not
139    pub fn include_slide_number_as_comment(mut self, value: bool) -> Self {
140        self.include_slide_number_as_comment = Some(value);
141        self
142    }
143
144    /// Sets whether speaker notes are appended to Markdown as blockquotes.
145    pub fn include_speaker_notes(mut self, value: bool) -> Self {
146        self.include_speaker_notes = Some(value);
147        self
148    }
149
150    /// Sets whether presentation comments are appended to Markdown as blockquotes.
151    pub fn include_comments(mut self, value: bool) -> Self {
152        self.include_comments = Some(value);
153        self
154    }
155
156    /// Sets whether presentation-wide Markdown includes the metadata header.
157    /// Metadata is parsed regardless of this setting.
158    pub fn include_presentation_metadata(mut self, value: bool) -> Self {
159        self.include_presentation_metadata = Some(value);
160        self
161    }
162
163    /// Builds the final [`ParserConfig`] instance, applying default values for any fields that were not set.
164    pub fn build(self) -> ParserConfig {
165        ParserConfig {
166            extract_images: self.extract_images.unwrap_or(true),
167            compress_images: self.compress_images.unwrap_or(true),
168            quality: self.image_quality.unwrap_or(80),
169            image_handling_mode: self
170                .image_handling_mode
171                .unwrap_or(ImageHandlingMode::InMarkdown),
172            image_output_path: self.image_output_path,
173            include_slide_number_as_comment: self.include_slide_number_as_comment.unwrap_or(true),
174            include_speaker_notes: self.include_speaker_notes.unwrap_or(false),
175            include_comments: self.include_comments.unwrap_or(false),
176            include_presentation_metadata: self.include_presentation_metadata.unwrap_or(true),
177        }
178    }
179}
180
181#[cfg(test)]
182#[path = "../tests/unit/parser_config.rs"]
183mod tests;