package LatexIndent::FileExtension; # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # See http://www.gnu.org/licenses/. # # Chris Hughes, 2017 # # For all communication, please visit: https://github.com/cmhughes/latexindent.pl use strict; use warnings; use PerlIO::encoding; #use open ':std', ':encoding(UTF-8)'; use File::Basename; # to get the filename and directory path use Exporter qw/import/; use Encode qw/decode/; use LatexIndent::GetYamlSettings qw/%mainSettings/; use LatexIndent::Switches qw/%switches $is_check_switch_active/; use LatexIndent::LogFile qw/$logger/; our @EXPORT_OK = qw/file_extension_check/; use LatexIndent::UTF8CmdLineArgsFileOperation qw/copy_with_encode exist_with_encode open_with_encode zero_with_encode read_yaml_with_encode/; use utf8; sub file_extension_check { my $self = shift; # grab the filename my $fileName = ${$self}{fileName}; # see if an extension exists for the fileName my ( $name, $dir, $ext ) = fileparse( $fileName, qr/\..[^.]*$/ ); # grab the file extension preferences my %fileExtensionPreference = %{ $mainSettings{fileExtensionPreference} }; # sort the file extensions by preference my @fileExtensions = sort { $fileExtensionPreference{$a} <=> $fileExtensionPreference{$b} } keys(%fileExtensionPreference); # store the base name ${$self}{baseName} = $name; # if no extension, search according to fileExtensionPreference if ( $fileName ne "-" ) { if ( !$ext ) { $logger->info("*File extension work:"); $logger->info( "latexindent called to act upon $fileName without a file extension;\nsearching for files in the following order (see fileExtensionPreference):" ); $logger->info( $fileName . join( "\n$fileName", @fileExtensions ) ); my $fileFound = 0; # loop through the known file extensions (see @fileExtensions) foreach (@fileExtensions) { if ( exist_with_encode( $fileName . $_ ) ) { $logger->info("$fileName$_ found!"); $fileName .= $_; $logger->info("Updated fileName to $fileName"); ${$self}{fileName} = $fileName; $fileFound = 1; $ext = $_; last; } } unless ($fileFound) { if ( defined ${$self}{multipleFiles} ) { $logger->warn( "*I couldn't find a match for $fileName in fileExtensionPreference (see defaultSettings.yaml)"); $logger->warn("moving on, no indentation done for ${$self}{fileName}."); return 3; } else { $logger->fatal( "*I couldn't find a match for $fileName in fileExtensionPreference (see defaultSettings.yaml)"); foreach (@fileExtensions) { $logger->fatal("I searched for $fileName$_"); } $logger->fatal("but couldn't find any of them.\nConsider updating fileExtensionPreference."); $logger->fatal("*Exiting, no indentation done."); $self->output_logfile(); exit(3); } } } else { # if the file has a recognised extension, check that the file exists unless ( exist_with_encode($fileName) ) { if ( defined ${$self}{multipleFiles} ) { $logger->warn("*I couldn't find $fileName, are you sure it exists?"); $logger->warn("moving on, no indentation done for ${$self}{fileName}."); return 3; } else { $logger->fatal("*I couldn't find $fileName, are you sure it exists?"); $logger->fatal("Exiting, no indentation done."); $self->output_logfile(); exit(3); } } } } # store the file extension ${$self}{fileExtension} = $ext; # check to see if -o switch is active if ( $switches{outputToFile} ) { $logger->info("*-o switch active: output file check"); # diacritics in file names (highlighted in https://github.com/cmhughes/latexindent.pl/pull/439) # # note, related: # # git config --add core.quotePath false ${$self}{outputToFile} = $switches{outputToFile}; if ( $fileName eq "-" and $switches{outputToFile} =~ m/^\+/ ) { $logger->info("STDIN input mode active, -o switch is removing all + symbols"); ${$self}{outputToFile} =~ s/\+//g; } # the -o file name might begin with a + symbol if ( $switches{outputToFile} =~ m/^\+(.*)/ and $1 ne "+" ) { $logger->info("-o switch called with + symbol at the beginning: ${$self}{outputToFile}"); ${$self}{outputToFile} = ${$self}{baseName} . $1; $logger->info("output file is now: ${$self}{outputToFile}"); } my $strippedFileExtension = ${$self}{fileExtension}; $strippedFileExtension =~ s/\.//; $strippedFileExtension = "tex" if ( $strippedFileExtension eq "" ); # grab the name, directory, and extension of the output file my ( $name, $dir, $ext ) = fileparse( ${$self}{outputToFile}, $strippedFileExtension ); # if there is no extension, then add the extension from the file to be operated upon if ( !$ext ) { $logger->info( "-o switch called with file name without extension: " . $switches{outputToFile} ); ${$self}{outputToFile} = $name . ( $name =~ m/\.\z/ ? q() : "." ) . $strippedFileExtension; $logger->info( "Updated to ${$self}{outputToFile} as the file extension of the input file is $strippedFileExtension"); } # the -o file name might end with ++ in which case we wish to search for existence, # and then increment accordingly $name =~ s/\.$//; if ( $name =~ m/\+\+$/ ) { $logger->info("-o switch called with file name ending with ++: ${$self}{outputToFile}"); $name =~ s/\+\+$//; $name = ${$self}{baseName} if ( $name eq "" ); my $outputFileCounter = 0; my $fileName = $name . $outputFileCounter . "." . $strippedFileExtension; $logger->info("will search for existence and increment counter, starting with $fileName"); while ( exist_with_encode($fileName) ) { $logger->info("$fileName exists, incrementing counter"); $outputFileCounter++; $fileName = $name . $outputFileCounter . "." . $strippedFileExtension; } $logger->info("$fileName does not exist, and will be the output file"); ${$self}{outputToFile} = $fileName; } } # read the file into the Document body my @lines; if ( $fileName ne "-" ) { my $openFilePossible = 1; my $MAINFILE = open_with_encode( '<:encoding(UTF-8)', $fileName ) or ( $openFilePossible = 0 ); if ( $openFilePossible == 0 ) { if ( defined ${$self}{multipleFiles} ) { $logger->warn("*$fileName exists, but could not open it"); $logger->warn("moving on, no indentation done for $fileName"); return 4; } else { $logger->fatal("*$fileName exists, but could not open it"); $logger->fatal("Exiting, no indentation done."); $self->output_logfile(); exit(4); } } push( @lines, $_ ) while (<$MAINFILE>); close($MAINFILE); } else { push( @lines, $_ ) while (<>); } # -n, --lines mode active if ( $switches{lines} ) { $self->lines_body_selected_lines( \@lines ); } else { # the all-important step: update the body ${$self}{body} = join( "", @lines ); } # necessary extra storage if # # check switch is active # # or # # $switches{overwriteIfDifferent} # if ( $is_check_switch_active or $switches{overwriteIfDifferent} ) { ${$self}{originalBody} = ${$self}{body}; } return 0; } 1;