@@ -74,6 +74,7 @@ impl<'a> OgImageAuthorData<'a> {
7474/// generating PNG images from a Typst template.
7575pub struct OgImageGenerator {
7676 typst_binary_path : PathBuf ,
77+ typst_font_path : Option < PathBuf > ,
7778}
7879
7980impl 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