@@ -240,33 +240,10 @@ func getConfig() Config {
240240
241241 // Check for command line argument first
242242 if len (os .Args ) > 1 {
243- inputPath = os .Args [1 ]
244-
245- // If format is provided as second argument, use it; otherwise use default 10x15cm
246- if len (os .Args ) > 2 {
247- formatArg := os .Args [2 ]
248- predefinedFormats := getPredefinedFormats ()
249-
250- switch formatArg {
251- case "10x15" , "1" :
252- selectedFormat = predefinedFormats [0 ]
253- case "13x18" , "2" :
254- selectedFormat = predefinedFormats [1 ]
255- default :
256- fmt .Printf ("Invalid format '%s'. Using default 10x15cm format.\n " , formatArg )
257- selectedFormat = predefinedFormats [0 ]
258- }
259- } else {
260- // Default to 10x15cm format for command line usage
261- predefinedFormats := getPredefinedFormats ()
262- selectedFormat = predefinedFormats [0 ]
263- fmt .Printf ("Using default format: %s\n " , selectedFormat .Name )
264- }
243+ inputPath , selectedFormat = parseCommandLineArgs ()
265244 } else {
266245 // Interactive mode
267- fmt .Print ("Enter path to input image: " )
268- input , _ := reader .ReadString ('\n' )
269- inputPath = strings .TrimSpace (input )
246+ inputPath = getInteractiveInputPath (reader )
270247
271248 // Get predefined formats with dynamic calculation
272249 predefinedFormats := getPredefinedFormats ()
@@ -336,6 +313,111 @@ func getConfig() Config {
336313 }
337314}
338315
316+ // parseCommandLineArgs handles command line argument parsing with support for file paths containing spaces
317+ func parseCommandLineArgs () (string , PrintFormat ) {
318+ predefinedFormats := getPredefinedFormats ()
319+
320+ // Strategy 1: Try to reconstruct file path from multiple arguments
321+ // Look for a valid file by combining arguments until we find an existing file
322+ var inputPath string
323+ var formatArg string
324+
325+ // Try different combinations of arguments to find the actual file path
326+ for i := 1 ; i < len (os .Args ); i ++ {
327+ // Build potential file path from os.Args[1] to os.Args[i]
328+ potentialPath := strings .Join (os .Args [1 :i + 1 ], " " )
329+
330+ // Check if this path exists
331+ if _ , err := os .Stat (potentialPath ); err == nil {
332+ inputPath = potentialPath
333+ // Remaining arguments after the file path could be format
334+ if i + 1 < len (os .Args ) {
335+ formatArg = os .Args [i + 1 ]
336+ }
337+ break
338+ }
339+ }
340+
341+ // If no valid file found by reconstruction, use the first argument as-is
342+ // (this maintains backward compatibility for properly quoted paths)
343+ if inputPath == "" {
344+ inputPath = os .Args [1 ]
345+ if len (os .Args ) > 2 {
346+ formatArg = os .Args [2 ]
347+ }
348+ }
349+
350+ // Parse format argument
351+ var selectedFormat PrintFormat
352+ if formatArg != "" {
353+ switch formatArg {
354+ case "10x15" , "1" :
355+ selectedFormat = predefinedFormats [0 ]
356+ case "13x18" , "2" :
357+ selectedFormat = predefinedFormats [1 ]
358+ default :
359+ fmt .Printf ("Invalid format '%s'. Using default 10x15cm format.\n " , formatArg )
360+ selectedFormat = predefinedFormats [0 ]
361+ }
362+ } else {
363+ // Default to 10x15cm format for command line usage
364+ selectedFormat = predefinedFormats [0 ]
365+ fmt .Printf ("Using default format: %s\n " , selectedFormat .Name )
366+ }
367+
368+ return inputPath , selectedFormat
369+ }
370+
371+ // getInteractiveInputPath handles interactive path input with enhanced error handling and path cleaning
372+ func getInteractiveInputPath (reader * bufio.Reader ) string {
373+ for {
374+ fmt .Print ("Enter path to input image: " )
375+ input , _ := reader .ReadString ('\n' )
376+ inputPath := strings .TrimSpace (input )
377+
378+ // Handle common issues with interactive input
379+ inputPath = cleanInputPath (inputPath )
380+
381+ // Check if file exists
382+ if _ , err := os .Stat (inputPath ); err == nil {
383+ return inputPath
384+ }
385+
386+ // File doesn't exist - provide helpful error message
387+ fmt .Printf ("❌ File not found: %s\n " , inputPath )
388+ fmt .Println ("💡 Tips:" )
389+ fmt .Println (" - Use tab completion to auto-complete paths" )
390+ fmt .Println (" - For paths with spaces, you can:" )
391+ fmt .Println (" • Use quotes: \" /path/with spaces/file.jpg\" " )
392+ fmt .Println (" • Let tab completion handle escaping" )
393+ fmt .Println (" • Just type the path normally (spaces are OK)" )
394+ fmt .Print ("\n " )
395+ }
396+ }
397+
398+ // cleanInputPath cleans up common issues with user-entered paths
399+ func cleanInputPath (path string ) string {
400+ // Remove surrounding quotes if present
401+ if len (path ) >= 2 {
402+ if (path [0 ] == '"' && path [len (path )- 1 ] == '"' ) ||
403+ (path [0 ] == '\'' && path [len (path )- 1 ] == '\'' ) {
404+ path = path [1 : len (path )- 1 ]
405+ }
406+ }
407+
408+ // Handle escaped spaces (convert "\ " back to " ")
409+ path = strings .ReplaceAll (path , "\\ " , " " )
410+
411+ // Expand tilde to home directory if needed
412+ if strings .HasPrefix (path , "~/" ) {
413+ if homeDir , err := os .UserHomeDir (); err == nil {
414+ path = filepath .Join (homeDir , path [2 :])
415+ }
416+ }
417+
418+ return path
419+ }
420+
339421func loadImage (path string ) (image.Image , error ) {
340422 file , err := os .Open (path )
341423 if err != nil {
0 commit comments