Skip to content

Commit 59e796d

Browse files
committed
og_image: Support custom font paths via TYPST_FONT_PATH environment variable
1 parent 57c3a6a commit 59e796d

File tree

1 file changed

+64
-18
lines changed
  • crates/crates_io_og_image/src

1 file changed

+64
-18
lines changed

crates/crates_io_og_image/src/lib.rs

Lines changed: 64 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ impl<'a> OgImageAuthorData<'a> {
7474
/// generating PNG images from a Typst template.
7575
pub struct OgImageGenerator {
7676
typst_binary_path: PathBuf,
77+
typst_font_path: Option<PathBuf>,
7778
}
7879

7980
impl OgImageGenerator {
@@ -88,7 +89,10 @@ impl OgImageGenerator {
8889
/// let generator = OgImageGenerator::new(PathBuf::from("/usr/local/bin/typst"));
8990
/// ```
9091
pub fn new(typst_binary_path: PathBuf) -> Self {
91-
Self { typst_binary_path }
92+
Self {
93+
typst_binary_path,
94+
typst_font_path: None,
95+
}
9296
}
9397

9498
/// Creates a new `OgImageGenerator` using the `TYPST_PATH` environment variable.
@@ -105,11 +109,43 @@ impl OgImageGenerator {
105109
/// # Ok::<(), crates_io_og_image::OgImageError>(())
106110
/// ```
107111
pub fn from_environment() -> Result<Self, OgImageError> {
108-
if let Some(path) = var("TYPST_PATH").map_err(OgImageError::EnvVarError)? {
109-
Ok(Self::new(PathBuf::from(path)))
112+
let typst_path = var("TYPST_PATH").map_err(OgImageError::EnvVarError)?;
113+
let font_path = var("TYPST_FONT_PATH").map_err(OgImageError::EnvVarError)?;
114+
115+
let mut generator = if let Some(path) = typst_path {
116+
Self::new(PathBuf::from(path))
110117
} else {
111-
Ok(Self::default())
118+
Self::default()
119+
};
120+
121+
if let Some(font_path) = font_path {
122+
let current_dir = std::env::current_dir()?;
123+
let font_path = current_dir.join(font_path).canonicalize()?;
124+
generator = generator.with_font_path(font_path);
112125
}
126+
127+
Ok(generator)
128+
}
129+
130+
/// Sets the font path for the Typst compiler.
131+
///
132+
/// This allows specifying a custom directory where Typst will look for fonts
133+
/// during compilation. Setting a custom font directory implies using the
134+
/// `--ignore-system-fonts` flag of the Typst CLI. If not set, Typst will
135+
/// use its default font discovery.
136+
///
137+
/// # Examples
138+
///
139+
/// ```
140+
/// use std::path::PathBuf;
141+
/// use crates_io_og_image::OgImageGenerator;
142+
///
143+
/// let generator = OgImageGenerator::default()
144+
/// .with_font_path(PathBuf::from("/usr/share/fonts"));
145+
/// ```
146+
pub fn with_font_path(mut self, font_path: PathBuf) -> Self {
147+
self.typst_font_path = Some(font_path);
148+
self
113149
}
114150

115151
/// Processes avatars by downloading URLs and copying assets to the assets directory.
@@ -239,20 +275,30 @@ impl OgImageGenerator {
239275
let json_avatar_map = json_avatar_map.map_err(OgImageError::JsonSerializationError)?;
240276

241277
// Run typst compile command with input data
242-
let output = Command::new(&self.typst_binary_path)
243-
.arg("compile")
244-
.arg("--format")
245-
.arg("png")
246-
.arg("--input")
247-
.arg(format!("data={}", json_data))
248-
.arg("--input")
249-
.arg(format!("avatar_map={}", json_avatar_map))
250-
.arg(&typ_file_path)
251-
.arg(output_file.path())
252-
.env_clear()
253-
.output()
254-
.await
255-
.map_err(OgImageError::TypstNotFound)?;
278+
let mut command = Command::new(&self.typst_binary_path);
279+
280+
command.arg("compile").arg("--format").arg("png");
281+
282+
// Pass in the data and avatar map as JSON inputs
283+
let input = format!("data={}", json_data);
284+
command.arg("--input").arg(input);
285+
let input = format!("avatar_map={}", json_avatar_map);
286+
command.arg("--input").arg(input);
287+
288+
// Pass in the font path if specified
289+
if let Some(font_path) = &self.typst_font_path {
290+
command.arg("--font-path").arg(font_path);
291+
command.arg("--ignore-system-fonts");
292+
}
293+
294+
// Pass input and output file paths
295+
command.arg(&typ_file_path).arg(output_file.path());
296+
297+
// Clear environment variables to avoid leaking sensitive data
298+
command.env_clear();
299+
300+
let output = command.output().await;
301+
let output = output.map_err(OgImageError::TypstNotFound)?;
256302

257303
if !output.status.success() {
258304
let stderr = String::from_utf8_lossy(&output.stderr).to_string();

0 commit comments

Comments
 (0)