@@ -10,16 +10,17 @@ use clap::Parser;
10
10
use tinymist_project:: WorldProvider ;
11
11
use typlite:: { common:: Format , TypliteFeat } ;
12
12
use typlite:: { CompileOnceArgs , Typlite } ;
13
+ use typst:: foundations:: Bytes ;
13
14
14
15
/// Common arguments of compile, watch, and query.
15
16
#[ derive( Debug , Clone , Parser , Default ) ]
16
17
pub struct CompileArgs {
17
18
#[ clap( flatten) ]
18
19
pub compile : CompileOnceArgs ,
19
20
20
- /// Path to output file(s)
21
- #[ clap( value_name = "OUTPUT" , action = clap :: ArgAction :: Append ) ]
22
- pub outputs : Vec < String > ,
21
+ /// Path to output file
22
+ #[ clap( value_name = "OUTPUT" , default_value = None ) ]
23
+ pub output : Option < String > ,
23
24
24
25
/// Configures the path of assets directory
25
26
#[ clap( long, default_value = None , value_name = "ASSETS_PATH" ) ]
@@ -36,13 +37,17 @@ fn main() -> typlite::Result<()> {
36
37
. as_ref ( )
37
38
. ok_or ( "Missing required argument: INPUT" ) ?;
38
39
39
- let outputs = if args. outputs . is_empty ( ) {
40
- vec ! [ Path :: new( input)
41
- . with_extension( "md" )
42
- . to_string_lossy( )
43
- . to_string( ) ]
44
- } else {
45
- args. outputs . clone ( )
40
+ let is_stdout = args. output . as_deref ( ) == Some ( "-" ) ;
41
+ let output_path = args
42
+ . output
43
+ . map ( PathBuf :: from)
44
+ . unwrap_or_else ( || Path :: new ( input) . with_extension ( "md" ) ) ;
45
+
46
+ let output_format = match output_path. extension ( ) {
47
+ Some ( ext) if ext == std:: ffi:: OsStr :: new ( "tex" ) => Format :: LaTeX ,
48
+ #[ cfg( feature = "docx" ) ]
49
+ Some ( ext) if ext == std:: ffi:: OsStr :: new ( "docx" ) => Format :: Docx ,
50
+ _ => Format :: Md ,
46
51
} ;
47
52
48
53
let assets_path = match args. assets_path {
@@ -65,102 +70,22 @@ fn main() -> typlite::Result<()> {
65
70
assets_path : assets_path. clone ( ) ,
66
71
..Default :: default ( )
67
72
} ) ;
68
- let doc = match converter. convert_doc ( ) {
69
- Ok ( doc) => doc,
70
- Err ( err) => return Err ( format ! ( "failed to convert document: {err}" ) . into ( ) ) ,
71
- } ;
72
-
73
- for output_path in & outputs {
74
- let is_stdout = output_path == "-" ;
75
- let output = if is_stdout {
76
- None
77
- } else {
78
- Some ( PathBuf :: from ( output_path) )
79
- } ;
73
+ let doc = converter. convert_doc ( output_format) ?;
80
74
81
- let format = match & output {
82
- Some ( output) if output. extension ( ) == Some ( std:: ffi:: OsStr :: new ( "tex" ) ) => {
83
- Format :: LaTeX
84
- }
85
- #[ cfg( feature = "docx" ) ]
86
- Some ( output) if output. extension ( ) == Some ( std:: ffi:: OsStr :: new ( "docx" ) ) => {
87
- Format :: Docx
88
- }
89
- _ => Format :: Md ,
90
- } ;
91
-
92
- match format {
93
- #[ cfg( feature = "docx" ) ]
94
- Format :: Docx => {
95
- let docx_data = match doc. to_docx ( ) {
96
- Ok ( data) => data,
97
- Err ( err) => {
98
- eprintln ! ( "Error generating DOCX for {}: {}" , output_path, err) ;
99
- continue ;
100
- }
101
- } ;
75
+ let result = match output_format {
76
+ Format :: Md => Bytes :: from_string ( doc. to_md_string ( ) ?) ,
77
+ Format :: LaTeX => Bytes :: from_string ( doc. to_tex_string ( true ) ?) ,
78
+ #[ cfg( feature = "docx" ) ]
79
+ Format :: Docx => Bytes :: new ( doc. to_docx ( ) ?) ,
80
+ } ;
102
81
103
- match output {
104
- None => {
105
- eprintln ! ( "output file is required for DOCX format" ) ;
106
- continue ;
107
- }
108
- Some ( output) => {
109
- if let Err ( err) = std:: fs:: write ( & output, docx_data) {
110
- eprintln ! ( "failed to write DOCX file {}: {}" , output. display( ) , err) ;
111
- continue ;
112
- }
113
- println ! ( "Generated DOCX file: {}" , output. display( ) ) ;
114
- }
115
- }
116
- }
117
- Format :: LaTeX => {
118
- let result = doc. to_tex_string ( true ) ;
119
- match ( result, output) {
120
- ( Ok ( content) , None ) => {
121
- std:: io:: stdout ( )
122
- . write_all ( content. as_str ( ) . as_bytes ( ) )
123
- . unwrap ( ) ;
124
- }
125
- ( Ok ( content) , Some ( output) ) => {
126
- if let Err ( err) = std:: fs:: write ( & output, content. as_str ( ) ) {
127
- eprintln ! ( "failed to write LaTeX file {}: {}" , output. display( ) , err) ;
128
- continue ;
129
- }
130
- println ! ( "Generated LaTeX file: {}" , output. display( ) ) ;
131
- }
132
- ( Err ( err) , _) => {
133
- eprintln ! ( "Error converting to LaTeX for {}: {}" , output_path, err) ;
134
- continue ;
135
- }
136
- }
137
- }
138
- Format :: Md => {
139
- let result = doc. to_md_string ( ) ;
140
- match ( result, output) {
141
- ( Ok ( content) , None ) => {
142
- std:: io:: stdout ( )
143
- . write_all ( content. as_str ( ) . as_bytes ( ) )
144
- . unwrap ( ) ;
145
- }
146
- ( Ok ( content) , Some ( output) ) => {
147
- if let Err ( err) = std:: fs:: write ( & output, content. as_str ( ) ) {
148
- eprintln ! (
149
- "failed to write Markdown file {}: {}" ,
150
- output. display( ) ,
151
- err
152
- ) ;
153
- continue ;
154
- }
155
- println ! ( "Generated Markdown file: {}" , output. display( ) ) ;
156
- }
157
- ( Err ( err) , _) => {
158
- eprintln ! ( "Error converting to Markdown for {}: {}" , output_path, err) ;
159
- continue ;
160
- }
161
- }
162
- }
163
- }
82
+ if is_stdout {
83
+ std:: io:: stdout ( ) . write_all ( result. as_slice ( ) ) . unwrap ( ) ;
84
+ } else if let Err ( err) = std:: fs:: write ( & output_path, result. as_slice ( ) ) {
85
+ Err ( format ! (
86
+ "failed to write file {}: {err}" ,
87
+ output_path. display( )
88
+ ) ) ?;
164
89
}
165
90
166
91
Ok ( ( ) )
0 commit comments