Skip to content

Commit b52fd4c

Browse files
authored
chore: allow specifying path for temporary export files (#518)
This adds a `--export-temporary-path` that allows using some specific path to store intermediate files used when exporting to pdf (currently an html and a css file) rather than using a temporary path. This helps debugging #516 but is also generally useful.
2 parents 3ef9d75 + 3f3b66b commit b52fd4c

File tree

3 files changed

+55
-13
lines changed

3 files changed

+55
-13
lines changed

src/export/exporter.rs

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,38 @@ use crossterm::{
2424
terminal::{Clear, ClearType},
2525
};
2626
use image::ImageError;
27-
use std::{fs, io, path::Path, rc::Rc, thread::sleep, time::Duration};
27+
use std::{
28+
fs, io,
29+
path::{Path, PathBuf},
30+
rc::Rc,
31+
thread::sleep,
32+
time::Duration,
33+
};
34+
use tempfile::TempDir;
35+
36+
pub enum OutputDirectory {
37+
Temporary(TempDir),
38+
External(PathBuf),
39+
}
40+
41+
impl OutputDirectory {
42+
pub fn temporary() -> io::Result<Self> {
43+
let dir = TempDir::with_suffix("presenterm")?;
44+
Ok(Self::Temporary(dir))
45+
}
46+
47+
pub fn external(path: PathBuf) -> io::Result<Self> {
48+
fs::create_dir_all(&path)?;
49+
Ok(Self::External(path))
50+
}
51+
52+
pub(crate) fn path(&self) -> &Path {
53+
match self {
54+
Self::Temporary(temp) => temp.path(),
55+
Self::External(path) => path,
56+
}
57+
}
58+
}
2859

2960
/// Allows exporting presentations into PDF.
3061
pub struct Exporter<'a> {
@@ -65,7 +96,11 @@ impl<'a> Exporter<'a> {
6596
/// Export the given presentation into PDF.
6697
///
6798
/// This uses a separate `presenterm-export` tool.
68-
pub fn export_pdf(mut self, presentation_path: &Path) -> Result<(), ExportError> {
99+
pub fn export_pdf(
100+
mut self,
101+
presentation_path: &Path,
102+
output_directory: OutputDirectory,
103+
) -> Result<(), ExportError> {
69104
println!(
70105
"exporting using rows={}, columns={}, width={}, height={}",
71106
self.dimensions.rows, self.dimensions.columns, self.dimensions.width, self.dimensions.height
@@ -91,7 +126,7 @@ impl<'a> Exporter<'a> {
91126
.build(elements)?;
92127
Self::validate_theme_colors(&presentation)?;
93128

94-
let mut render = PdfRender::new(self.dimensions)?;
129+
let mut render = PdfRender::new(self.dimensions, output_directory);
95130
Self::log("waiting for images to be generated and code to be executed, if any...")?;
96131
for slide in presentation.iter_slides_mut() {
97132
Self::render_async_images(slide);

src/export/pdf.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::exporter::ExportError;
1+
use super::exporter::{ExportError, OutputDirectory};
22
use crate::{
33
markdown::text_style::{Color, TextStyle},
44
presentation::Slide,
@@ -18,7 +18,6 @@ use std::{
1818
fs, io,
1919
path::{Path, PathBuf},
2020
};
21-
use tempfile::TempDir;
2221

2322
// A magical multiplier that converts a font size in pixels to a font width.
2423
//
@@ -130,14 +129,13 @@ impl HtmlSlide {
130129
}
131130

132131
pub(crate) struct ContentManager {
133-
output_directory: TempDir,
132+
output_directory: OutputDirectory,
134133
image_count: usize,
135134
}
136135

137136
impl ContentManager {
138-
pub(crate) fn new() -> io::Result<Self> {
139-
let output_directory = TempDir::with_suffix("presenterm")?;
140-
Ok(Self { output_directory, image_count: 0 })
137+
pub(crate) fn new(output_directory: OutputDirectory) -> Self {
138+
Self { output_directory, image_count: 0 }
141139
}
142140

143141
fn persist_image(&mut self, image: &Image) -> Result<PathBuf, ExportError> {
@@ -177,9 +175,9 @@ pub(crate) struct PdfRender {
177175
}
178176

179177
impl PdfRender {
180-
pub(crate) fn new(dimensions: WindowSize) -> io::Result<Self> {
181-
let image_manager = ContentManager::new()?;
182-
Ok(Self { content_manager: image_manager, dimensions, html_body: "".to_string(), background_color: None })
178+
pub(crate) fn new(dimensions: WindowSize, output_directory: OutputDirectory) -> Self {
179+
let image_manager = ContentManager::new(output_directory);
180+
Self { content_manager: image_manager, dimensions, html_body: "".to_string(), background_color: None }
183181
}
184182

185183
pub(crate) fn process_slide(&mut self, slide: Slide) -> Result<(), ExportError> {

src/main.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ use crossterm::{
2525
style::{PrintStyledContent, Stylize},
2626
};
2727
use directories::ProjectDirs;
28+
use export::exporter::OutputDirectory;
2829
use render::properties::WindowSize;
2930
use std::{
3031
env::{self, current_dir},
@@ -69,6 +70,10 @@ struct Cli {
6970
#[clap(short, long)]
7071
export_pdf: bool,
7172

73+
/// The path in which to store temporary files used when exporting.
74+
#[clap(long, requires = "export_pdf")]
75+
export_temporary_path: Option<PathBuf>,
76+
7277
/// Generate a JSON schema for the configuration file.
7378
#[clap(long)]
7479
generate_config_file_schema: bool,
@@ -407,7 +412,11 @@ fn run(cli: Cli) -> Result<(), Box<dyn std::error::Error>> {
407412
builder_options,
408413
dimensions,
409414
);
410-
exporter.export_pdf(&path)?;
415+
let output_directory = match cli.export_temporary_path {
416+
Some(path) => OutputDirectory::external(path),
417+
None => OutputDirectory::temporary(),
418+
}?;
419+
exporter.export_pdf(&path, output_directory)?;
411420
} else {
412421
let SpeakerNotesComponents { events_listener, events_publisher } =
413422
SpeakerNotesComponents::new(&cli, &config, &path)?;

0 commit comments

Comments
 (0)