@@ -12,7 +12,7 @@ use crate::options::{GnuplotVersion, MultiplotFillDirection, MultiplotFillOrder}
1212use crate :: util:: escape;
1313use crate :: writer:: Writer ;
1414use std:: fs:: File ;
15- use std:: io:: { BufWriter , Write } ;
15+ use std:: io:: { BufWriter , Read , Write } ;
1616use std:: path:: { Path , PathBuf } ;
1717use std:: process:: { Child , Command , Stdio } ;
1818use std:: str;
@@ -99,6 +99,11 @@ impl CloseSentinel
9999 CloseSentinel { gnuplot }
100100 }
101101
102+ pub fn stdout ( & mut self ) -> Option < impl Read >
103+ {
104+ self . gnuplot . stdout . take ( )
105+ }
106+
102107 /// Waits until the gnuplot process exits. See `std::process::Child::wait`.
103108 pub fn wait ( & mut self ) -> std:: io:: Result < std:: process:: ExitStatus >
104109 {
@@ -121,13 +126,20 @@ impl Drop for CloseSentinel
121126 }
122127}
123128
129+ pub enum OutPutStream
130+ {
131+ Inherit ,
132+ Piped ,
133+ }
134+
124135/// A figure that may contain multiple axes.
125136pub struct Figure
126137{
127138 axes : Vec < AxesVariant > ,
128139 terminal : String ,
129140 enhanced_text : bool ,
130141 output_file : Option < PathBuf > ,
142+ output_stream : OutPutStream ,
131143 post_commands : String ,
132144 pre_commands : String ,
133145 // RefCell so that we can echo to it
@@ -165,6 +177,7 @@ impl Figure
165177 terminal : "" . into ( ) ,
166178 enhanced_text : true ,
167179 output_file : None ,
180+ output_stream : OutPutStream :: Inherit ,
168181 gnuplot : None ,
169182 post_commands : "" . into ( ) ,
170183 pre_commands : "" . into ( ) ,
@@ -233,6 +246,13 @@ impl Figure
233246 self
234247 }
235248
249+ // Set where gnuplot output should be streamed to
250+ pub fn set_output_stream ( & mut self , output_stream : OutPutStream ) -> & mut Figure
251+ {
252+ self . output_stream = output_stream;
253+ self
254+ }
255+
236256 /// Set or unset text enhancements
237257 pub fn set_enhanced_text ( & mut self , enhanced : bool ) -> & mut Figure
238258 {
@@ -382,6 +402,23 @@ impl Figure
382402 self
383403 }
384404
405+ fn update_cached_version ( & mut self ) -> std:: io:: Result < ( ) >
406+ {
407+ let output = Command :: new ( "gnuplot" ) . arg ( "--version" ) . output ( ) ?;
408+ if let Ok ( version_string) = str:: from_utf8 ( & output. stdout )
409+ {
410+ let parts: Vec < _ > = version_string. split ( [ ' ' , '.' ] ) . collect ( ) ;
411+ if parts. len ( ) > 2 && parts[ 0 ] == "gnuplot"
412+ {
413+ if let ( Ok ( major) , Ok ( minor) ) = ( parts[ 1 ] . parse :: < i32 > ( ) , parts[ 2 ] . parse :: < i32 > ( ) )
414+ {
415+ self . version = Some ( GnuplotVersion { major, minor } ) ;
416+ }
417+ }
418+ }
419+ Ok ( ( ) )
420+ }
421+
385422 /// Launch a gnuplot process, if it hasn't been spawned already by a call to
386423 /// this function, and display the figure on it.
387424 ///
@@ -397,20 +434,7 @@ impl Figure
397434
398435 if self . version . is_none ( )
399436 {
400- let output = Command :: new ( "gnuplot" ) . arg ( "--version" ) . output ( ) ?;
401-
402- if let Ok ( version_string) = str:: from_utf8 ( & output. stdout )
403- {
404- let parts: Vec < _ > = version_string. split ( [ ' ' , '.' ] ) . collect ( ) ;
405- if parts. len ( ) > 2 && parts[ 0 ] == "gnuplot"
406- {
407- if let ( Ok ( major) , Ok ( minor) ) =
408- ( parts[ 1 ] . parse :: < i32 > ( ) , parts[ 2 ] . parse :: < i32 > ( ) )
409- {
410- self . version = Some ( GnuplotVersion { major, minor } ) ;
411- }
412- }
413- }
437+ self . update_cached_version ( ) ?
414438 }
415439
416440 if self . gnuplot . is_none ( )
@@ -419,6 +443,11 @@ impl Figure
419443 Command :: new ( "gnuplot" )
420444 . arg ( "-p" )
421445 . stdin ( Stdio :: piped ( ) )
446+ . stdout ( match self . output_stream
447+ {
448+ OutPutStream :: Inherit => Stdio :: inherit ( ) ,
449+ OutPutStream :: Piped => Stdio :: piped ( ) ,
450+ } )
422451 . spawn ( )
423452 . expect (
424453 "Couldn't spawn gnuplot. Make sure it is installed and available in PATH." ,
@@ -458,6 +487,34 @@ impl Figure
458487 Ok ( CloseSentinel :: new ( gnuplot) )
459488 }
460489
490+ pub fn output_string ( & mut self ) -> Result < String , GnuplotInitError >
491+ {
492+ if self . axes . is_empty ( )
493+ {
494+ return Ok ( "" . to_string ( ) ) ;
495+ }
496+
497+ if self . version . is_none ( )
498+ {
499+ self . update_cached_version ( ) ?
500+ }
501+
502+ let mut gnuplot = Command :: new ( "gnuplot" )
503+ . arg ( "-p" )
504+ . stdin ( Stdio :: piped ( ) )
505+ . stdout ( Stdio :: piped ( ) )
506+ . spawn ( )
507+ . expect ( "Couldn't spawn gnuplot. Make sure it is installed and available in PATH." ) ;
508+
509+ let stdin = gnuplot. stdin . as_mut ( ) . expect ( "No stdin!?" ) ;
510+ self . echo ( stdin) ;
511+ stdin. flush ( ) ;
512+
513+ let output = gnuplot. wait_with_output ( ) ?;
514+ let o = output. stdout . as_slice ( ) ;
515+ Ok ( String :: from_utf8_lossy ( o) . to_string ( ) )
516+ }
517+
461518 /// Save the figure to a png file.
462519 ///
463520 /// # Arguments
0 commit comments