diff options
author | Karl Berry <karl@freefriends.org> | 2022-04-14 19:48:17 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2022-04-14 19:48:17 +0000 |
commit | 96b00a78469d97b34c7e89477725a37ab3fd32a1 (patch) | |
tree | ba28851cb504e6bf89c53af1151df2724b58c991 /Master/texmf-dist/scripts | |
parent | d3eb5a117030fe207ad30748d79b0bb0755529fd (diff) |
latexindent (14apr22)
git-svn-id: svn://tug.org/texlive/trunk@63027 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/scripts')
42 files changed, 5071 insertions, 4096 deletions
diff --git a/Master/texmf-dist/scripts/latexindent/LatexIndent/AlignmentAtAmpersand.pm b/Master/texmf-dist/scripts/latexindent/LatexIndent/AlignmentAtAmpersand.pm index 6607bf6c9d4..746041893d7 100644 --- a/Master/texmf-dist/scripts/latexindent/LatexIndent/AlignmentAtAmpersand.pm +++ b/Master/texmf-dist/scripts/latexindent/LatexIndent/AlignmentAtAmpersand.pm @@ -1,4 +1,5 @@ package LatexIndent::AlignmentAtAmpersand; + # 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 @@ -26,33 +27,34 @@ use LatexIndent::Tokens qw/%tokens/; use LatexIndent::LogFile qw/$logger/; use LatexIndent::HiddenChildren qw/%familyTree/; use LatexIndent::Verbatim qw/%verbatimStorage/; -our @ISA = "LatexIndent::Document"; # class inheritance, Programming Perl, pg 321 -our @EXPORT_OK = qw/align_at_ampersand find_aligned_block double_back_slash_else main_formatting individual_padding multicolumn_padding multicolumn_pre_check multicolumn_post_check dont_measure hidden_child_cell_row_width hidden_child_row_width get_column_width/; +our @ISA = "LatexIndent::Document"; # class inheritance, Programming Perl, pg 321 +our @EXPORT_OK + = qw/align_at_ampersand find_aligned_block double_back_slash_else main_formatting individual_padding multicolumn_padding multicolumn_pre_check multicolumn_post_check dont_measure hidden_child_cell_row_width hidden_child_row_width get_column_width/; our $alignmentBlockCounter; -our @cellStorage; # two-dimensional storage array containing the cell information -our @formattedBody; # array for the new body +our @cellStorage; # two-dimensional storage array containing the cell information +our @formattedBody; # array for the new body our @minMultiColSpan; our @maxColumnWidth; our @maxDelimiterWidth; -sub find_aligned_block{ +sub find_aligned_block { my $self = shift; - return unless (${$self}{body} =~ m/(?!<\\)%\*\h*\\begin\{/s); + return unless ( ${$self}{body} =~ m/(?!<\\)%\*\h*\\begin\{/s ); # aligned block - # %* \begin{tabular} - # 1 & 2 & 3 & 4 \\ - # 5 & & 6 & \\ - # %* \end{tabular} - $logger->trace('*Searching for ALIGNED blocks marked by comments')if($is_t_switch_active); - $logger->trace(Dumper(\%{$mainSettings{lookForAlignDelims}})) if($is_tt_switch_active); - while( my ($alignmentBlock,$yesno)= each %{$mainSettings{lookForAlignDelims}}){ - if(ref $yesno eq "HASH"){ - $yesno = (defined ${$yesno}{delims} ) ? ${$yesno}{delims} : 1; - } - if($yesno){ + # %* \begin{tabular} + # 1 & 2 & 3 & 4 \\ + # 5 & & 6 & \\ + # %* \end{tabular} + $logger->trace('*Searching for ALIGNED blocks marked by comments') if ($is_t_switch_active); + $logger->trace( Dumper( \%{ $mainSettings{lookForAlignDelims} } ) ) if ($is_tt_switch_active); + while ( my ( $alignmentBlock, $yesno ) = each %{ $mainSettings{lookForAlignDelims} } ) { + if ( ref $yesno eq "HASH" ) { + $yesno = ( defined ${$yesno}{delims} ) ? ${$yesno}{delims} : 1; + } + if ($yesno) { $logger->trace("looking for %*\\begin\{$alignmentBlock\} environments"); my $alignmentRegExp = qr/ @@ -78,9 +80,9 @@ sub find_aligned_block{ ) /sx; - while( ${$self}{body} =~ m/$alignmentRegExp/sx){ + while ( ${$self}{body} =~ m/$alignmentRegExp/sx ) { - ${$self}{body} =~ s/ + ${$self}{body} =~ s/ $alignmentRegExp / # create a new Environment object @@ -104,23 +106,24 @@ sub find_aligned_block{ ${@{${$self}{children}}[-1]}{replacementText}; /xseg; - } - } else { + } + } + else { $logger->trace("*not* looking for $alignmentBlock as $alignmentBlock:$yesno"); - } + } } return; } -sub yaml_modify_line_breaks_settings{ +sub yaml_modify_line_breaks_settings { return; } -sub tasks_particular_to_each_object{ +sub tasks_particular_to_each_object { return; } -sub create_unique_id{ +sub create_unique_id { my $self = shift; $alignmentBlockCounter++; @@ -128,55 +131,56 @@ sub create_unique_id{ return; } -sub align_at_ampersand{ +sub align_at_ampersand { my $self = shift; - return if(${$self}{bodyLineBreaks}==0); + return if ( ${$self}{bodyLineBreaks} == 0 ); # some blocks may contain verbatim to be measured - ${$self}{measureVerbatim} = (${$self}{body}=~m/$tokens{verbatim}/ ? 1 : 0); + ${$self}{measureVerbatim} = ( ${$self}{body} =~ m/$tokens{verbatim}/ ? 1 : 0 ); my $maximumNumberOfAmpersands = 0; # clear the global arrays - @formattedBody = (); - @cellStorage = (); - @minMultiColSpan = (); - @maxColumnWidth = (); + @formattedBody = (); + @cellStorage = (); + @minMultiColSpan = (); + @maxColumnWidth = (); @maxDelimiterWidth = (); # maximum column widths my @maximumColumnWidths; - my $rowCounter = -1; + my $rowCounter = -1; my $columnCounter = -1; - $logger->trace("*dontMeasure routine, row mode") if(${$self}{dontMeasure} and $is_t_switch_active); + $logger->trace("*dontMeasure routine, row mode") if ( ${$self}{dontMeasure} and $is_t_switch_active ); # initial loop for column storage and measuring # initial loop for column storage and measuring # initial loop for column storage and measuring - foreach(split("\n",${$self}{body})){ + foreach ( split( "\n", ${$self}{body} ) ) { $rowCounter++; # default is to measure this row, but it can be switched off by the dont_measure routine ${$self}{measureRow} = 1; # call the dont_measure routine - $self->dont_measure(mode=>"row",row=>$_) if ${$self}{dontMeasure}; + $self->dont_measure( mode => "row", row => $_ ) if ${$self}{dontMeasure}; # remove \\ and anything following it my $endPiece = q(); - if($_ =~ m/(\\\\.*)/){ - if(${$self}{alignFinalDoubleBackSlash} ){ + if ( $_ =~ m/(\\\\.*)/ ) { + if ( ${$self}{alignFinalDoubleBackSlash} ) { + # for example, if we want: # # Name & \shortstack{Hi \\ Lo} \\ <!--- Note this row! # Foo & Bar \\ # # in the first row, note that the first \\ - # needs to be ignored, and we align by - # the final double back slash - + # needs to be ignored, and we align by + # the final double back slash + $_ =~ s/(\\\\ (?: (?! @@ -185,7 +189,8 @@ sub align_at_ampersand{ )*?$ # non-greedy )//sx; $endPiece = $1; - } else { + } + else { $_ =~ s/(\\\\.*)//; $endPiece = $1; } @@ -193,9 +198,9 @@ sub align_at_ampersand{ # remove any trailing comments my $trailingComments; - if($_ =~ m/$trailingCommentRegExp/ ){ + if ( $_ =~ m/$trailingCommentRegExp/ ) { $_ =~ s/($trailingCommentRegExp)//; - $trailingComments = $1; + $trailingComments = $1; } # some rows shouldn't be formatted @@ -205,7 +210,7 @@ sub align_at_ampersand{ # # (?<!\\)& # - # which is set in GetYamlSettings.pm, but can be set + # which is set in GetYamlSettings.pm, but can be set # by the user using, for example # # lookForAlignDelims: @@ -215,46 +220,48 @@ sub align_at_ampersand{ my $delimiterRegEx = qr/${$self}{delimiterRegEx}/; my $numberOfAmpersands = () = $_ =~ /$delimiterRegEx/g; - $maximumNumberOfAmpersands = $numberOfAmpersands if($numberOfAmpersands>$maximumNumberOfAmpersands); - + $maximumNumberOfAmpersands = $numberOfAmpersands if ( $numberOfAmpersands > $maximumNumberOfAmpersands ); + # remove space at the beginning of a row, surrounding &, and at the end of the row $_ =~ s/(?<!\\)\h*($delimiterRegEx)\h*/$1/g; $_ =~ s/^\h*//g; $_ =~ s/\h*$//g; - + # if the line finishes with an &, then add an empty space, # otherwise the column count is off - $_ .= ($_ =~ m/$delimiterRegEx$/ ? " ":q()); + $_ .= ( $_ =~ m/$delimiterRegEx$/ ? " " : q() ); - # store the columns, which are either split by & + # store the columns, which are either split by & # or otherwise simply the current line, if for example, the current line simply # contains \multicolumn{8}... \\ (see test-cases/texexchange/366841-zarko.tex, for example) - my @columns = ($_ =~ m/$delimiterRegEx/ ? split(/($delimiterRegEx)/,$_) : $_); + my @columns = ( $_ =~ m/$delimiterRegEx/ ? split( /($delimiterRegEx)/, $_ ) : $_ ); $columnCounter = -1; my $spanning = 0; - foreach my $column (@columns){ - # if a column contains only the delimiter, then we need to + foreach my $column (@columns) { + + # if a column contains only the delimiter, then we need to # - measure it # - add it and its length to the previous cell # - remove it from the columns array # - if($column =~ m/$delimiterRegEx/) { - # update the delimiter to be used, and its associated length + if ( $column =~ m/$delimiterRegEx/ ) { + + # update the delimiter to be used, and its associated length # for the *previous* cell - my $spanningOffSet = ($spanning > 0 ? $spanning - 1 : 0); - ${$cellStorage[$rowCounter][$columnCounter - $spanningOffSet]}{delimiter} = $1; - ${$cellStorage[$rowCounter][$columnCounter - $spanningOffSet]}{delimiterLength} = &get_column_width($1); + my $spanningOffSet = ( $spanning > 0 ? $spanning - 1 : 0 ); + ${ $cellStorage[$rowCounter][ $columnCounter - $spanningOffSet ] }{delimiter} = $1; + ${ $cellStorage[$rowCounter][ $columnCounter - $spanningOffSet ] }{delimiterLength} + = &get_column_width($1); # keep track of maximum delimiter width - $maxDelimiterWidth[$columnCounter - $spanningOffSet] = - (defined $maxDelimiterWidth[$columnCounter - $spanningOffSet] - ? - max($maxDelimiterWidth[$columnCounter-$spanningOffSet], - ${$cellStorage[$rowCounter][$columnCounter-$spanningOffSet]}{delimiterLength}) - : - ${$cellStorage[$rowCounter][$columnCounter - $spanningOffSet]}{delimiterLength}); + $maxDelimiterWidth[ $columnCounter - $spanningOffSet ] = ( + defined $maxDelimiterWidth[ $columnCounter - $spanningOffSet ] + ? max( $maxDelimiterWidth[ $columnCounter - $spanningOffSet ], + ${ $cellStorage[$rowCounter][ $columnCounter - $spanningOffSet ] }{delimiterLength} ) + : ${ $cellStorage[$rowCounter][ $columnCounter - $spanningOffSet ] }{delimiterLength} + ); # importantly, move on to the next column! next; @@ -266,76 +273,90 @@ sub align_at_ampersand{ # reset spanning (only applicable if multiColumnGrouping) $spanning = 0; - # if a column has finished with a \ then we need to add a trailing space, + # if a column has finished with a \ then we need to add a trailing space, # otherwise the \ can be put next to &. See test-cases/texexchange/112343-gonzalo for example - $column .= ($column =~ m/\\$/ ? " ": q()); + $column .= ( $column =~ m/\\$/ ? " " : q() ); # basic cell storage - $cellStorage[$rowCounter][$columnCounter] - = ({width=>&get_column_width($column), - entry=>$column, - type=>($numberOfAmpersands>0 ? "X" : "*"), - groupPadding=>0, - colSpan=>".", - delimiter=>"", - delimiterLength=>0, - measureThis=> ($numberOfAmpersands>0 ? ${$self}{measureRow} : 0) }); - + $cellStorage[$rowCounter][$columnCounter] = ( + { width => &get_column_width($column), + entry => $column, + type => ( $numberOfAmpersands > 0 ? "X" : "*" ), + groupPadding => 0, + colSpan => ".", + delimiter => "", + delimiterLength => 0, + measureThis => ( $numberOfAmpersands > 0 ? ${$self}{measureRow} : 0 ) + } + ); + # possible hidden children, see https://github.com/cmhughes/latexindent.pl/issues/85 - if ( (${$self}{measureHiddenChildren} or ${$self}{measureVerbatim} ) - and $column =~m/.*?$tokens{beginOfToken}/s){ - $self->hidden_child_cell_row_width($column,$rowCounter,$columnCounter); + if ( ( ${$self}{measureHiddenChildren} or ${$self}{measureVerbatim} ) + and $column =~ m/.*?$tokens{beginOfToken}/s ) + { + $self->hidden_child_cell_row_width( $column, $rowCounter, $columnCounter ); } - # store the maximum column width - $maxColumnWidth[$columnCounter] = (defined $maxColumnWidth[$columnCounter] - ? - max($maxColumnWidth[$columnCounter],${$cellStorage[$rowCounter][$columnCounter]}{width}) - : - ${$cellStorage[$rowCounter][$columnCounter]}{width} ) if ${$cellStorage[$rowCounter][$columnCounter]}{type} eq "X"; - + # store the maximum column width + $maxColumnWidth[$columnCounter] = ( + defined $maxColumnWidth[$columnCounter] + ? max( $maxColumnWidth[$columnCounter], ${ $cellStorage[$rowCounter][$columnCounter] }{width} ) + : ${ $cellStorage[$rowCounter][$columnCounter] }{width} + ) if ${ $cellStorage[$rowCounter][$columnCounter] }{type} eq "X"; + # \multicolumn cell - if(${$self}{multiColumnGrouping} and $column =~ m/\\multicolumn\{(\d+)\}/ and $1>1){ + if ( ${$self}{multiColumnGrouping} and $column =~ m/\\multicolumn\{(\d+)\}/ and $1 > 1 ) { $spanning = $1; # adjust the type - ${$cellStorage[$rowCounter][$columnCounter]}{type} = "$spanning"; + ${ $cellStorage[$rowCounter][$columnCounter] }{type} = "$spanning"; # some \multicol cells can have their spanning information removed from type # so we store it in colSpan as well - ${$cellStorage[$rowCounter][$columnCounter]}{colSpan} = $spanning; + ${ $cellStorage[$rowCounter][$columnCounter] }{colSpan} = $spanning; # and don't measure it - ${$cellStorage[$rowCounter][$columnCounter]}{measureThis} = 0; + ${ $cellStorage[$rowCounter][$columnCounter] }{measureThis} = 0; # create 'gap' columns - for(my $j=$columnCounter+1; $j<=$columnCounter+($spanning-1);$j++){ - $cellStorage[$rowCounter][$j] = ({type=>"-", - entry=>'', - width=>0, - individualPadding=>0, - groupPadding=>0, - colSpan=>".", - delimiter=>"", - delimiterLength=>0, - measureThis=>0}); + for ( my $j = $columnCounter + 1; $j <= $columnCounter + ( $spanning - 1 ); $j++ ) { + $cellStorage[$rowCounter][$j] = ( + { type => "-", + entry => '', + width => 0, + individualPadding => 0, + groupPadding => 0, + colSpan => ".", + delimiter => "", + delimiterLength => 0, + measureThis => 0 + } + ); } - + # store the minimum spanning value - $minMultiColSpan[$columnCounter] = (defined $minMultiColSpan[$columnCounter] ? min($minMultiColSpan[$columnCounter],$spanning) : $spanning ); + $minMultiColSpan[$columnCounter] = ( + defined $minMultiColSpan[$columnCounter] + ? min( $minMultiColSpan[$columnCounter], $spanning ) + : $spanning + ); # adjust the column counter $columnCounter += $spanning - 1; - } + } } # store the information - push(@formattedBody,{row=>$_, - endPiece=>$endPiece, - trailingComment=>$trailingComments, - numberOfAmpersands=>$numberOfAmpersands, - unformattedRow=>$unformattedRow }); - + push( + @formattedBody, + { row => $_, + endPiece => $endPiece, + trailingComment => $trailingComments, + numberOfAmpersands => $numberOfAmpersands, + unformattedRow => $unformattedRow + } + ); + } # store the maximum number of ampersands @@ -343,7 +364,7 @@ sub align_at_ampersand{ # blocks with nested multicolumns need some pre checking $self->multicolumn_pre_check if ${$self}{multiColumnGrouping}; - + # maximum column width loop, and individual padding $self->individual_padding; @@ -354,8 +375,13 @@ sub align_at_ampersand{ $self->multicolumn_post_check if ${$self}{multiColumnGrouping}; # output to log file - if( $is_t_switch_active ){ - &pretty_print_cell_info($_) for ("entry","type","colSpan","width","measureThis","maximumColumnWidth","individualPadding","groupPadding","delimiter","delimiterLength"); + if ($is_t_switch_active) { + &pretty_print_cell_info($_) + for ( + "entry", "type", "colSpan", "width", + "measureThis", "maximumColumnWidth", "individualPadding", "groupPadding", + "delimiter", "delimiterLength" + ); } # main formatting loop @@ -364,43 +390,59 @@ sub align_at_ampersand{ # final \\ loop # final \\ loop # final \\ loop - foreach (@formattedBody){ + foreach (@formattedBody) { + # reset the padding my $padding = q(); # possibly adjust the padding - if(${$_}{row} !~ m/^\h*$/){ + if ( ${$_}{row} !~ m/^\h*$/ ) { + # remove trailing horizontal space if ${$self}{alignDoubleBackSlash} is set to 0 - ${$_}{row} =~ s/\h*$// if (!${$self}{alignDoubleBackSlash}); - + ${$_}{row} =~ s/\h*$// if ( !${$self}{alignDoubleBackSlash} ); + # format spacing infront of \\ - if(defined ${$self}{spacesBeforeDoubleBackSlash} and ${$self}{spacesBeforeDoubleBackSlash}<0 and !${$self}{alignDoubleBackSlash}){ + if ( defined ${$self}{spacesBeforeDoubleBackSlash} + and ${$self}{spacesBeforeDoubleBackSlash} < 0 + and !${$self}{alignDoubleBackSlash} ) + { # zero spaces (possibly resulting in un-aligned \\) $padding = q(); - } elsif(defined ${$self}{spacesBeforeDoubleBackSlash} and ${$self}{spacesBeforeDoubleBackSlash}>=0 and !${$self}{alignDoubleBackSlash}){ + } + elsif ( defined ${$self}{spacesBeforeDoubleBackSlash} + and ${$self}{spacesBeforeDoubleBackSlash} >= 0 + and !${$self}{alignDoubleBackSlash} ) + { # specified number of spaces (possibly resulting in un-aligned \\) - $padding = " " x (${$self}{spacesBeforeDoubleBackSlash}); - } else { + $padding = " " x ( ${$self}{spacesBeforeDoubleBackSlash} ); + } + else { # aligned \\ - $padding = " " x max(0,(${$self}{maximumRowWidth} - ${$_}{rowWidth})); + $padding = " " x max( 0, ( ${$self}{maximumRowWidth} - ${$_}{rowWidth} ) ); } } # format the row, and put the trailing \\ and trailing comments back into the row - ${$_}{row} .= $padding.(${$_}{endPiece} ? ${$_}{endPiece} :q() ).(${$_}{trailingComment}? ${$_}{trailingComment} : q() ); + ${$_}{row} + .= $padding + . ( ${$_}{endPiece} ? ${$_}{endPiece} : q() ) + . ( ${$_}{trailingComment} ? ${$_}{trailingComment} : q() ); # some rows shouldn't be formatted, and may only have trailing comments; # see test-cases/alignment/table4.tex for example - if( (${$_}{numberOfAmpersands} == 0 and !${$_}{endPiece}) - or - (${$_}{numberOfAmpersands} < ${$self}{maximumNumberOfAmpersands} and !${$self}{alignRowsWithoutMaxDelims} and !${$_}{endPiece}) - ){ - ${$_}{row} = (${$_}{unformattedRow} ne "" ? ${$_}{unformattedRow}:q()).(${$_}{trailingComment}?${$_}{trailingComment}:q()); + if (( ${$_}{numberOfAmpersands} == 0 and !${$_}{endPiece} ) + or ( ${$_}{numberOfAmpersands} < ${$self}{maximumNumberOfAmpersands} + and !${$self}{alignRowsWithoutMaxDelims} + and !${$_}{endPiece} ) + ) + { + ${$_}{row} = ( ${$_}{unformattedRow} ne "" ? ${$_}{unformattedRow} : q() ) + . ( ${$_}{trailingComment} ? ${$_}{trailingComment} : q() ); } - + # spaces for leadingBlankColumn in operation - if(${$self}{leadingBlankColumn}>-1){ - $padding = " " x (${$self}{leadingBlankColumn}); + if ( ${$self}{leadingBlankColumn} > -1 ) { + $padding = " " x ( ${$self}{leadingBlankColumn} ); ${$_}{row} =~ s/^\h*/$padding/s; } } @@ -409,9 +451,9 @@ sub align_at_ampersand{ ${$self}{body} = q(); # update the body - ${$self}{body} .= ${$_}{row}."\n" for @formattedBody; + ${$self}{body} .= ${$_}{row} . "\n" for @formattedBody; - # if the \end{} statement didn't originally have a line break before it, we need to remove the final + # if the \end{} statement didn't originally have a line break before it, we need to remove the final # line break added by the above ${$self}{body} =~ s/\h*\R$//s if !${$self}{linebreaksAtEnd}{body}; @@ -434,23 +476,25 @@ sub align_at_ampersand{ # # see https://github.com/cmhughes/latexindent.pl/issues/223 for example - if (!${${$self}{linebreaksAtEnd}}{begin} - and ${$cellStorage[0][0]}{type} eq "X" - and ${$cellStorage[0][0]}{measureThis}){ + if ( !${ ${$self}{linebreaksAtEnd} }{begin} + and ${ $cellStorage[0][0] }{type} eq "X" + and ${ $cellStorage[0][0] }{measureThis} ) + { my $lengthOfBegin = ${$self}{begin}; - if( (${$self}{begin} eq '{' | ${$self}{begin} eq '[') and ${$self}{parentBegin}){ - $lengthOfBegin = ${$self}{parentBegin}."{"; + if ( ( ${$self}{begin} eq '{' | ${$self}{begin} eq '[' ) and ${$self}{parentBegin} ) { + $lengthOfBegin = ${$self}{parentBegin} . "{"; } - ${$self}{indentation} = " " x (&get_column_width($lengthOfBegin)); - $logger->trace("Adjusting indentation of ${$self}{name} in AlignAtAmpersand routine") if($is_t_switch_active); + ${$self}{indentation} = " " x ( &get_column_width($lengthOfBegin) ); + $logger->trace("Adjusting indentation of ${$self}{name} in AlignAtAmpersand routine") if ($is_t_switch_active); } - } +} sub main_formatting { + # PURPOSE: # (1) perform the *padding* operations - # by adding + # by adding # # <spacesBeforeAmpersand> # & @@ -460,7 +504,7 @@ sub main_formatting { # the justification being LEFT or RIGHT # # (2) measure the row width and store - # the maximum row width for use with + # the maximum row width for use with # the (possible) alignment of the \\ # my $self = shift; @@ -470,95 +514,102 @@ sub main_formatting { # objective (1): padding # objective (1): padding # objective (1): padding - - $logger->trace("*formatted rows for: ${$self}{name}") if($is_t_switch_active); + + $logger->trace("*formatted rows for: ${$self}{name}") if ($is_t_switch_active); my $rowCount = -1; + # row loop foreach my $row (@cellStorage) { - $rowCount++; - - # clear the temporary row - my $tmpRow = q(); - - # column loop - foreach my $cell (@$row) { - if (${$cell}{type} eq "*" or ${$cell}{type} eq "-"){ - $tmpRow .= ${$cell}{entry}; - next; - } - - # the placement of the padding is dependent on the value of justification - if(${$self}{justification} eq "left"){ - # LEFT: - # LEFT: - # LEFT: - # <cell entry> <individual padding> <group padding> ... - $tmpRow .= ${$cell}{entry}; - $tmpRow .= " " x ${$cell}{individualPadding}; - $tmpRow .= " " x ${$cell}{groupPadding}; - } else { - # RIGHT: - # RIGHT: - # RIGHT: - # <group padding> <individual padding> <cell entry> ... - $tmpRow .= " " x ${$cell}{groupPadding}; - $tmpRow .= " " x ${$cell}{individualPadding}; - $tmpRow .= ${$cell}{entry}; - } - - # either way, finish with: <spacesBeforeAmpersand> & <spacesAfterAmpersand> - $tmpRow .= " " x ${$self}{spacesBeforeAmpersand}; - $tmpRow .= ${$cell}{delimiter}; - $tmpRow .= " " x ${$self}{spacesAfterAmpersand}; - } - - # if alignRowsWithoutMaxDelims = 0 - # and there are *less than* the maximum number of ampersands, then - # we undo all of the work above! - if( !${$self}{alignRowsWithoutMaxDelims} - and - ${$formattedBody[$rowCount]}{numberOfAmpersands} < ${$self}{maximumNumberOfAmpersands} ){ - $tmpRow = ${$formattedBody[$rowCount]}{unformattedRow}; - } - - # spacing before \\ - my $finalSpacing = q(); - $finalSpacing = " " x (${$self}{spacesBeforeDoubleBackSlash}) if ${$self}{spacesBeforeDoubleBackSlash}>=1; - $tmpRow =~ s/\h*$/$finalSpacing/; - - # if $tmpRow is made up of only horizontal space, then empty it - $tmpRow = q() if($tmpRow =~ m/^\h*$/); - - # to the log file - $logger->trace($tmpRow) if($is_t_switch_active); - - # store this formatted row - ${$formattedBody[$rowCount]}{row} = $tmpRow; - - # objective (2): calculate row width and update maximumRowWidth - # objective (2): calculate row width and update maximumRowWidth - # objective (2): calculate row width and update maximumRowWidth - my $rowWidth = &get_column_width($tmpRow); - - # possibly update rowWidth if there are hidden children; see test-cases/alignment/hidden-child1.tex and friends - $rowWidth = $self->hidden_child_row_width($tmpRow,$rowCount,$rowWidth) if(${$self}{measureHiddenChildren} or ${$self}{measureVerbatim}); - - ${$formattedBody[$rowCount]}{rowWidth} = $rowWidth; - - # update the maximum row width - if( $rowWidth > ${$self}{maximumRowWidth} - and !(${$formattedBody[$rowCount]}{numberOfAmpersands} == 0 and !${$formattedBody[$rowCount]}{endPiece}) ){ - ${$self}{maximumRowWidth} = $rowWidth; - } + $rowCount++; + + # clear the temporary row + my $tmpRow = q(); + + # column loop + foreach my $cell (@$row) { + if ( ${$cell}{type} eq "*" or ${$cell}{type} eq "-" ) { + $tmpRow .= ${$cell}{entry}; + next; + } + + # the placement of the padding is dependent on the value of justification + if ( ${$self}{justification} eq "left" ) { + + # LEFT: + # LEFT: + # LEFT: + # <cell entry> <individual padding> <group padding> ... + $tmpRow .= ${$cell}{entry}; + $tmpRow .= " " x ${$cell}{individualPadding}; + $tmpRow .= " " x ${$cell}{groupPadding}; + } + else { + # RIGHT: + # RIGHT: + # RIGHT: + # <group padding> <individual padding> <cell entry> ... + $tmpRow .= " " x ${$cell}{groupPadding}; + $tmpRow .= " " x ${$cell}{individualPadding}; + $tmpRow .= ${$cell}{entry}; + } + + # either way, finish with: <spacesBeforeAmpersand> & <spacesAfterAmpersand> + $tmpRow .= " " x ${$self}{spacesBeforeAmpersand}; + $tmpRow .= ${$cell}{delimiter}; + $tmpRow .= " " x ${$self}{spacesAfterAmpersand}; + } + + # if alignRowsWithoutMaxDelims = 0 + # and there are *less than* the maximum number of ampersands, then + # we undo all of the work above! + if ( !${$self}{alignRowsWithoutMaxDelims} + and ${ $formattedBody[$rowCount] }{numberOfAmpersands} < ${$self}{maximumNumberOfAmpersands} ) + { + $tmpRow = ${ $formattedBody[$rowCount] }{unformattedRow}; + } + + # spacing before \\ + my $finalSpacing = q(); + $finalSpacing = " " x ( ${$self}{spacesBeforeDoubleBackSlash} ) if ${$self}{spacesBeforeDoubleBackSlash} >= 1; + $tmpRow =~ s/\h*$/$finalSpacing/; + + # if $tmpRow is made up of only horizontal space, then empty it + $tmpRow = q() if ( $tmpRow =~ m/^\h*$/ ); + + # to the log file + $logger->trace($tmpRow) if ($is_t_switch_active); + + # store this formatted row + ${ $formattedBody[$rowCount] }{row} = $tmpRow; + + # objective (2): calculate row width and update maximumRowWidth + # objective (2): calculate row width and update maximumRowWidth + # objective (2): calculate row width and update maximumRowWidth + my $rowWidth = &get_column_width($tmpRow); + + # possibly update rowWidth if there are hidden children; see test-cases/alignment/hidden-child1.tex and friends + $rowWidth = $self->hidden_child_row_width( $tmpRow, $rowCount, $rowWidth ) + if ( ${$self}{measureHiddenChildren} or ${$self}{measureVerbatim} ); + + ${ $formattedBody[$rowCount] }{rowWidth} = $rowWidth; + + # update the maximum row width + if ( $rowWidth > ${$self}{maximumRowWidth} + and + !( ${ $formattedBody[$rowCount] }{numberOfAmpersands} == 0 and !${ $formattedBody[$rowCount] }{endPiece} ) ) + { + ${$self}{maximumRowWidth} = $rowWidth; + } } # log file information - if($is_tt_switch_active and ${$self}{measureHiddenChildren}){ + if ( $is_tt_switch_active and ${$self}{measureHiddenChildren} ) { $logger->info('*FamilyTree after align for ampersand'); - $logger->trace(Dumper(\%familyTree)) if($is_tt_switch_active); + $logger->trace( Dumper( \%familyTree ) ) if ($is_tt_switch_active); $rowCount = -1; + # row loop foreach my $row (@cellStorage) { $rowCount++; @@ -567,48 +618,59 @@ sub main_formatting { } } -sub dont_measure{ +sub dont_measure { - my $self = shift; + my $self = shift; my %input = @_; - if( $input{mode} eq "cell" - and ref(\${$self}{dontMeasure}) eq "SCALAR" - and ${$self}{dontMeasure} eq "largest" - and ${$cellStorage[$input{row}][$input{column}]}{width} == $maxColumnWidth[$input{column}]){ + if ( $input{mode} eq "cell" + and ref( \${$self}{dontMeasure} ) eq "SCALAR" + and ${$self}{dontMeasure} eq "largest" + and ${ $cellStorage[ $input{row} ][ $input{column} ] }{width} == $maxColumnWidth[ $input{column} ] ) + { # dontMeasure stored as largest, for example # # lookForAlignDelims: - # tabular: + # tabular: # dontMeasure: largest - $logger->trace("CELL FOUND with maximum column width, $maxColumnWidth[$input{column}], and will not be measured (largest mode)") if($is_t_switch_active); - $logger->trace("column: ", $input{column}," width: ",${$cellStorage[$input{row}][$input{column}]}{width}) if($is_t_switch_active); - $logger->trace("entry: ", ${$cellStorage[$input{row}][$input{column}]}{entry}) if($is_t_switch_active); - $logger->trace("--------------------------") if($is_t_switch_active); - ${$cellStorage[$input{row}][$input{column}]}{measureThis} = 0; - ${$cellStorage[$input{row}][$input{column}]}{type} = "X"; - } elsif($input{mode} eq "cell" and (ref(${$self}{dontMeasure}) eq "ARRAY")){ - + $logger->trace( + "CELL FOUND with maximum column width, $maxColumnWidth[$input{column}], and will not be measured (largest mode)" + ) if ($is_t_switch_active); + $logger->trace( "column: ", $input{column}, " width: ", + ${ $cellStorage[ $input{row} ][ $input{column} ] }{width} ) + if ($is_t_switch_active); + $logger->trace( "entry: ", ${ $cellStorage[ $input{row} ][ $input{column} ] }{entry} ) if ($is_t_switch_active); + $logger->trace("--------------------------") if ($is_t_switch_active); + ${ $cellStorage[ $input{row} ][ $input{column} ] }{measureThis} = 0; + ${ $cellStorage[ $input{row} ][ $input{column} ] }{type} = "X"; + } + elsif ( $input{mode} eq "cell" and ( ref( ${$self}{dontMeasure} ) eq "ARRAY" ) ) { + # loop through the entries in dontMeasure - foreach(@{${$self}{dontMeasure}}){ - if(ref(\$_) eq "SCALAR" and ${$cellStorage[$input{row}][$input{column}]}{entry} eq $_){ + foreach ( @{ ${$self}{dontMeasure} } ) { + if ( ref( \$_ ) eq "SCALAR" and ${ $cellStorage[ $input{row} ][ $input{column} ] }{entry} eq $_ ) { + # dontMeasure stored as *strings*, for example: # # lookForAlignDelims: - # tabular: + # tabular: # dontMeasure: # - \multicolumn{1}{c}{Expiry} - # - Tenor - # - \multicolumn{1}{c}{$\Delta_{\text{call},10}$} - - $logger->trace("CELL FOUND (this): $_ and will not be measured") if($is_t_switch_active); - ${$cellStorage[$input{row}][$input{column}]}{measureThis} = 0; - ${$cellStorage[$input{row}][$input{column}]}{type} = "X"; - } elsif (ref($_) eq "HASH" and ${$_}{this} and ${$cellStorage[$input{row}][$input{column}]}{entry} eq ${$_}{this}){ + # - Tenor + # - \multicolumn{1}{c}{$\Delta_{\text{call},10}$} + + $logger->trace("CELL FOUND (this): $_ and will not be measured") if ($is_t_switch_active); + ${ $cellStorage[ $input{row} ][ $input{column} ] }{measureThis} = 0; + ${ $cellStorage[ $input{row} ][ $input{column} ] }{type} = "X"; + } + elsif ( ref($_) eq "HASH" + and ${$_}{this} + and ${ $cellStorage[ $input{row} ][ $input{column} ] }{entry} eq ${$_}{this} ) + { # for example: # # lookForAlignDelims: - # tabular: + # tabular: # dontMeasure: # - # this: \multicolumn{1}{c}{Expiry} @@ -617,19 +679,21 @@ sub dont_measure{ # OR (note that applyTo is optional): # # lookForAlignDelims: - # tabular: + # tabular: # dontMeasure: # - # this: \multicolumn{1}{c}{Expiry} - next if(defined ${$_}{applyTo} and !${$_}{applyTo} eq "cell" ); - $logger->trace("CELL FOUND (this): ${$_}{this} and will not be measured") if($is_t_switch_active); - ${$cellStorage[$input{row}][$input{column}]}{measureThis} = 0; - ${$cellStorage[$input{row}][$input{column}]}{type} = "X"; - } elsif (ref($_) eq "HASH" and ${$_}{regex} ){ + next if ( defined ${$_}{applyTo} and !${$_}{applyTo} eq "cell" ); + $logger->trace("CELL FOUND (this): ${$_}{this} and will not be measured") if ($is_t_switch_active); + ${ $cellStorage[ $input{row} ][ $input{column} ] }{measureThis} = 0; + ${ $cellStorage[ $input{row} ][ $input{column} ] }{type} = "X"; + } + elsif ( ref($_) eq "HASH" and ${$_}{regex} ) { + # for example: # # lookForAlignDelims: - # tabular: + # tabular: # dontMeasure: # - # regex: \multicolumn{1}{c}{Expiry} @@ -638,226 +702,239 @@ sub dont_measure{ # OR (note that applyTo is optional): # # lookForAlignDelims: - # tabular: + # tabular: # dontMeasure: # - # regex: \multicolumn{1}{c}{Expiry} - next if(defined ${$_}{applyTo} and !${$_}{applyTo} eq "cell" ); + next if ( defined ${$_}{applyTo} and !${$_}{applyTo} eq "cell" ); my $regex = qr/${$_}{regex}/; - next unless ${$cellStorage[$input{row}][$input{column}]}{entry} =~ m/${$_}{regex}/; - $logger->trace("CELL FOUND (regex): ${$_}{regex} and will not be measured") if($is_t_switch_active); - ${$cellStorage[$input{row}][$input{column}]}{measureThis} = 0; - ${$cellStorage[$input{row}][$input{column}]}{type} = "X"; + next unless ${ $cellStorage[ $input{row} ][ $input{column} ] }{entry} =~ m/${$_}{regex}/; + $logger->trace("CELL FOUND (regex): ${$_}{regex} and will not be measured") if ($is_t_switch_active); + ${ $cellStorage[ $input{row} ][ $input{column} ] }{measureThis} = 0; + ${ $cellStorage[ $input{row} ][ $input{column} ] }{type} = "X"; } } - } elsif($input{mode} eq "row" and (ref(${$self}{dontMeasure}) eq "ARRAY")){ - foreach(@{${$self}{dontMeasure}}){ + } + elsif ( $input{mode} eq "row" and ( ref( ${$self}{dontMeasure} ) eq "ARRAY" ) ) { + foreach ( @{ ${$self}{dontMeasure} } ) { + # move on, unless we have specified applyTo as row: # # lookForAlignDelims: - # tabular: + # tabular: # dontMeasure: # - # this: \multicolumn{1}{c}{Expiry} # applyTo: row # # note: *default value* of applyTo is cell - next unless (ref($_) eq "HASH" and defined ${$_}{applyTo} and ${$_}{applyTo} eq "row"); - if(${$_}{this} and $input{row} eq ${$_}{this}){ - $logger->trace("ROW FOUND (this): ${$_}{this}") if($is_t_switch_active); - $logger->trace("and will not be measured") if($is_t_switch_active); + next unless ( ref($_) eq "HASH" and defined ${$_}{applyTo} and ${$_}{applyTo} eq "row" ); + if ( ${$_}{this} and $input{row} eq ${$_}{this} ) { + $logger->trace("ROW FOUND (this): ${$_}{this}") if ($is_t_switch_active); + $logger->trace("and will not be measured") if ($is_t_switch_active); ${$self}{measureRow} = 0; - } elsif(${$_}{regex} and $input{row} =~ ${$_}{regex}){ - $logger->trace("ROW FOUND (regex): ${$_}{regex}") if($is_t_switch_active); - $logger->trace("and will not be measured") if($is_t_switch_active); + } + elsif ( ${$_}{regex} and $input{row} =~ ${$_}{regex} ) { + $logger->trace("ROW FOUND (regex): ${$_}{regex}") if ($is_t_switch_active); + $logger->trace("and will not be measured") if ($is_t_switch_active); ${$self}{measureRow} = 0; } } } } -sub individual_padding{ - # PURPOSE - # (1) the *primary* purpose of this routine is to - # measure the *individual padding* of - # each cell. - # - # for example, for - # - # 111 & 2 & 33333 \\ - # 4 & 55 & 66\\ - # - # then the individual padding will be - # - # 0 1 0 - # 2 0 3 - # - # this is calculated by looping - # through the rows & columns - # and finding the maximum column widths - # - # (2) the *secondary* purpose of this routine is to - # fill in any gaps in the @cellStorage array - # for any entries that don't yet exist; - # - # for example, - # 111 & 2 & 33333 \\ - # 4 & 55 & 66\\ - # 77 & 8 <------ GAP HERE - # - # there is a gap in @cellStorage in the final row, - # which is completed by the second loop in the below - - my $self = shift; - - # array to store maximum column widths - my @maximumColumnWidths; - - # we count the maximum number of columns - my $maximumNumberOfColumns = 0; - - # maximum column width loop - # maximum column width loop - # maximum column width loop - - $logger->trace("*dontMeasure routine, cell mode") if(${$self}{dontMeasure} and $is_t_switch_active); - - # row loop - my $rowCount = -1; - foreach my $row (@cellStorage) { - $rowCount++; - - # column loop - my $j = -1; - foreach my $cell (@$row) { - $j++; +sub individual_padding { - # if alignRowsWithoutMaxDelims = 0 - # and there are *less than* the maximum number of ampersands, then - # don't measure this column - if( !${$self}{alignRowsWithoutMaxDelims} - and - ${$formattedBody[$rowCount]}{numberOfAmpersands} < ${$self}{maximumNumberOfAmpersands} ){ - ${$cell}{measureThis} = 0; - ${$cell}{type} = "*"; - } + # PURPOSE + # (1) the *primary* purpose of this routine is to + # measure the *individual padding* of + # each cell. + # + # for example, for + # + # 111 & 2 & 33333 \\ + # 4 & 55 & 66\\ + # + # then the individual padding will be + # + # 0 1 0 + # 2 0 3 + # + # this is calculated by looping + # through the rows & columns + # and finding the maximum column widths + # + # (2) the *secondary* purpose of this routine is to + # fill in any gaps in the @cellStorage array + # for any entries that don't yet exist; + # + # for example, + # 111 & 2 & 33333 \\ + # 4 & 55 & 66\\ + # 77 & 8 <------ GAP HERE + # + # there is a gap in @cellStorage in the final row, + # which is completed by the second loop in the below - # check if the cell shouldn't be measured - $self->dont_measure(mode=>"cell",row=>$rowCount,column=>$j) if ${$self}{dontMeasure}; + my $self = shift; + + # array to store maximum column widths + my @maximumColumnWidths; + + # we count the maximum number of columns + my $maximumNumberOfColumns = 0; + + # maximum column width loop + # maximum column width loop + # maximum column width loop + + $logger->trace("*dontMeasure routine, cell mode") if ( ${$self}{dontMeasure} and $is_t_switch_active ); + + # row loop + my $rowCount = -1; + foreach my $row (@cellStorage) { + $rowCount++; + + # column loop + my $j = -1; + foreach my $cell (@$row) { + $j++; + + # if alignRowsWithoutMaxDelims = 0 + # and there are *less than* the maximum number of ampersands, then + # don't measure this column + if ( !${$self}{alignRowsWithoutMaxDelims} + and ${ $formattedBody[$rowCount] }{numberOfAmpersands} < ${$self}{maximumNumberOfAmpersands} ) + { + ${$cell}{measureThis} = 0; + ${$cell}{type} = "*"; + } + + # check if the cell shouldn't be measured + $self->dont_measure( mode => "cell", row => $rowCount, column => $j ) if ${$self}{dontMeasure}; + + # it's possible to have delimiters of different lengths, for example + # + # \begin{tabbing} + # 1 # 22 \> 333 # 4444 \\ + # xxx # aaa # yyyyy # zzzzzzzz \\ + # . # # & # \\ + # + # ^^ + # || + # \end{tabbing} + # + # note that this has a delimiter of \> (length 2) and # (length 1) + # + # furthermore, it's possible to specify the delimiter justification as "left" or "right" + if ( ${$cell}{delimiterLength} > 0 and ${$cell}{delimiterLength} < $maxDelimiterWidth[$j] ) { + if ( ${$self}{delimiterJustification} eq "left" ) { + ${$cell}{delimiter} .= " " x ( $maxDelimiterWidth[$j] - ${$cell}{delimiterLength} ); + } + elsif ( ${$self}{delimiterJustification} eq "right" ) { + ${$cell}{delimiter} + = " " x ( $maxDelimiterWidth[$j] - ${$cell}{delimiterLength} ) . ${$cell}{delimiter}; + } + + # update the delimiterLength + ${$cell}{delimiterLength} = $maxDelimiterWidth[$j]; + } + + # to keep leadingBlankColumn on, we need to check: + # + # - are we in the first column? + # - is leadingBlankColumn 0 or more? + # - cell width of first column equal 0? + # - are we measuring this cell? + # + # see test-cases/alignment/issue-275a.tex and the associated logfile + # + if ( $j == 0 and ${$self}{leadingBlankColumn} > -1 and ${$cell}{width} > 0 and ${$cell}{measureThis} == 1 ) + { + ${$self}{leadingBlankColumn} = -1; + } + + # there are some cells that shouldn't be accounted for in measuring, + # for example {ccc} + next if !${$cell}{measureThis}; + + # otherwise, make the measurement + $maximumColumnWidths[$j] = ( + defined $maximumColumnWidths[$j] + ? max( $maximumColumnWidths[$j], ${$cell}{width} ) + : ${$cell}{width} + ); - # it's possible to have delimiters of different lengths, for example - # - # \begin{tabbing} - # 1 # 22 \> 333 # 4444 \\ - # xxx # aaa # yyyyy # zzzzzzzz \\ - # . # # & # \\ - # - # ^^ - # || - # \end{tabbing} - # - # note that this has a delimiter of \> (length 2) and # (length 1) - # - # furthermore, it's possible to specify the delimiter justification as "left" or "right" - if(${$cell}{delimiterLength}>0 and ${$cell}{delimiterLength} < $maxDelimiterWidth[$j]){ - if(${$self}{delimiterJustification} eq "left"){ - ${$cell}{delimiter} .= " " x ($maxDelimiterWidth[$j] - ${$cell}{delimiterLength}); - } elsif(${$self}{delimiterJustification} eq "right") { - ${$cell}{delimiter} = " " x ($maxDelimiterWidth[$j] - ${$cell}{delimiterLength}).${$cell}{delimiter} ; - } - - # update the delimiterLength - ${$cell}{delimiterLength} = $maxDelimiterWidth[$j]; - } - - # to keep leadingBlankColumn on, we need to check: - # - # - are we in the first column? - # - is leadingBlankColumn 0 or more? - # - cell width of first column equal 0? - # - are we measuring this cell? - # - # see test-cases/alignment/issue-275a.tex and the associated logfile - # - if ($j==0 and ${$self}{leadingBlankColumn}>-1 and ${$cell}{width} > 0 and ${$cell}{measureThis}==1){ - ${$self}{leadingBlankColumn} = -1; } - - # there are some cells that shouldn't be accounted for in measuring, - # for example {ccc} - next if !${$cell}{measureThis}; - - # otherwise, make the measurement - $maximumColumnWidths[$j] = (defined $maximumColumnWidths[$j] - ? - max($maximumColumnWidths[$j],${$cell}{width}) - : - ${$cell}{width}); + # update the maximum number of columns + $maximumNumberOfColumns = $j if ( $j > $maximumNumberOfColumns ); } - # update the maximum number of columns - $maximumNumberOfColumns = $j if ( $j > $maximumNumberOfColumns ); - } - - # individual padding and gap filling loop - # individual padding and gap filling loop - # individual padding and gap filling loop - - # row loop - foreach my $row (@cellStorage) { - # column loop - foreach (my $j=0; $j <= $maximumNumberOfColumns; $j++){ - if( defined ${$row}[$j]){ - # individual padding - my $maximum = (defined $maximumColumnWidths[$j] ? $maximumColumnWidths[$j]: 0); - my $cellWidth = ${$row}[$j]{width}; - ${$row}[$j]{individualPadding} += ($maximum > $cellWidth ? $maximum - $cellWidth : 0); - } else { - # gap filling - ${$row}[$j] = ({type=>"-", - entry=>'', - width=>0, - individualPadding=>0, - groupPadding=>0, - measureThis=>0, - colSpan=>".", - delimiter=>"", - delimiterLength=>0, - }); - } + # individual padding and gap filling loop + # individual padding and gap filling loop + # individual padding and gap filling loop + + # row loop + foreach my $row (@cellStorage) { + + # column loop + foreach ( my $j = 0; $j <= $maximumNumberOfColumns; $j++ ) { + if ( defined ${$row}[$j] ) { + + # individual padding + my $maximum = ( defined $maximumColumnWidths[$j] ? $maximumColumnWidths[$j] : 0 ); + my $cellWidth = ${$row}[$j]{width}; + ${$row}[$j]{individualPadding} += ( $maximum > $cellWidth ? $maximum - $cellWidth : 0 ); + } + else { + # gap filling + ${$row}[$j] = ( + { type => "-", + entry => '', + width => 0, + individualPadding => 0, + groupPadding => 0, + measureThis => 0, + colSpan => ".", + delimiter => "", + delimiterLength => 0, + } + ); + } - # now the gaps have been filled, store the maximumColumnWidth for future reference - ${$row}[$j]{maximumColumnWidth} = (defined $maximumColumnWidths[$j] ? $maximumColumnWidths[$j] : 0); + # now the gaps have been filled, store the maximumColumnWidth for future reference + ${$row}[$j]{maximumColumnWidth} = ( defined $maximumColumnWidths[$j] ? $maximumColumnWidths[$j] : 0 ); + } } - } } sub multicolumn_pre_check { - # PURPOSE: - # ensure that multiple multicolumn commands are - # handled appropriately - # - # example 1 - # - # \multicolumn{2}{c}{thing} & \\ - # 111 & 2 & 33333 \\ - # 4 & 55 & 66 \\ - # \multicolumn{2}{c}{a} & \\ - # - # ^^^^^^^^ - # |||||||| - # - # the second multicolumn command should not be measured, but - # *should* receive individual padding + + # PURPOSE: + # ensure that multiple multicolumn commands are + # handled appropriately + # + # example 1 + # + # \multicolumn{2}{c}{thing} & \\ + # 111 & 2 & 33333 \\ + # 4 & 55 & 66 \\ + # \multicolumn{2}{c}{a} & \\ + # + # ^^^^^^^^ + # |||||||| + # + # the second multicolumn command should not be measured, but + # *should* receive individual padding my $self = shift; # loop through minMultiColSpan and add empty entries as necessary - foreach(@minMultiColSpan){ - $_ = "." if !(defined $_); + foreach (@minMultiColSpan) { + $_ = "." if !( defined $_ ); } - # ensure that only the *MINIMUM* multicolumn commands are designated + # ensure that only the *MINIMUM* multicolumn commands are designated # to be measured; for example: # # \multicolumn{2}{c|}{Ótimo humano} & Abuso da pontuação & Recompensas densas \\ @@ -867,21 +944,21 @@ sub multicolumn_pre_check { # the \multicolumn{2}{c|}{Ótimo humano} *is* the minimum multicolumn command # for the first column, and the \multicolumn{3}{c||}{Exploração Fácil} *is not* # to be measured - + # row loop my $rowCount = -1; foreach my $row (@cellStorage) { - $rowCount++; - - # column loop - my $j = -1; - foreach my $cell (@$row) { - $j++; - if( ${$cell}{type} =~ m/(\d)/ and ($1 >$minMultiColSpan[$j])){ - ${$cell}{type} = "X"; - ${$cell}{measureThis} = 0; + $rowCount++; + + # column loop + my $j = -1; + foreach my $cell (@$row) { + $j++; + if ( ${$cell}{type} =~ m/(\d)/ and ( $1 > $minMultiColSpan[$j] ) ) { + ${$cell}{type} = "X"; + ${$cell}{measureThis} = 0; + } } - } } # now loop back through and ensure that each of the \multicolumn commands @@ -890,62 +967,64 @@ sub multicolumn_pre_check { # row loop $rowCount = -1; foreach my $row (@cellStorage) { - $rowCount++; - - # column loop - my $j = -1; - foreach my $cell (@$row) { - $j++; - - # multicolumn entry - if(${$cell}{type} =~ m/(\d+)/) { - - my $multiColumnSpan = $1; - - # *inner* row loop - my $innerRowCount = -1; - foreach my $innerRow (@cellStorage) { - $innerRowCount++; - - # we only want to measure the *other* rows - next if($innerRowCount == $rowCount); - - # column loop - my $innerJ = -1; - foreach my $innerCell (@$innerRow) { - $innerJ++; - - if( $innerJ == $j and ${$innerCell}{type} =~ m/(\d)/ and $1 >= $multiColumnSpan){ - if(${$cell}{width} < ${$innerCell}{width}){ - ${$cell}{type} = "X"; - ${$cell}{measureThis} = 0; - ${$cell}{individualPadding} = (${$innerCell}{width} - ${$cell}{width} ); - } else { - ${$innerCell}{type} = "X"; - ${$innerCell}{measureThis} = 0; - ${$innerCell}{individualPadding} = (${$cell}{width} - ${$innerCell}{width}); - } - } - } - } + $rowCount++; + + # column loop + my $j = -1; + foreach my $cell (@$row) { + $j++; + + # multicolumn entry + if ( ${$cell}{type} =~ m/(\d+)/ ) { + + my $multiColumnSpan = $1; + + # *inner* row loop + my $innerRowCount = -1; + foreach my $innerRow (@cellStorage) { + $innerRowCount++; + + # we only want to measure the *other* rows + next if ( $innerRowCount == $rowCount ); + + # column loop + my $innerJ = -1; + foreach my $innerCell (@$innerRow) { + $innerJ++; + + if ( $innerJ == $j and ${$innerCell}{type} =~ m/(\d)/ and $1 >= $multiColumnSpan ) { + if ( ${$cell}{width} < ${$innerCell}{width} ) { + ${$cell}{type} = "X"; + ${$cell}{measureThis} = 0; + ${$cell}{individualPadding} = ( ${$innerCell}{width} - ${$cell}{width} ); + } + else { + ${$innerCell}{type} = "X"; + ${$innerCell}{measureThis} = 0; + ${$innerCell}{individualPadding} = ( ${$cell}{width} - ${$innerCell}{width} ); + } + } + } + } + } } - } - } + } } -sub multicolumn_padding{ +sub multicolumn_padding { + # PURPOSE: # assign multi column padding, for example: # # \multicolumn{2}{c}{thing}&\\ # 111 &2&33333 \\ - # 4& 55&66\\ + # 4& 55&66\\ # # needs to be transformed into # # \multicolumn{2}{c}{thing} & \\ # 111 & 2 & 33333 \\ - # 4 & 55 & 66 \\ + # 4 & 55 & 66 \\ # # ^^^^^^^^^^^^^^^ # ||||||||||||||| @@ -954,18 +1033,18 @@ sub multicolumn_padding{ # illustrated by the up arrows in the above # # Approach: - # (1) measure the "grouping widths" under/above each of the + # (1) measure the "grouping widths" under/above each of the # \multicolumn entries; these are stored within # - # groupingWidth + # groupingWidth # - # for the relevant column entries; in the - # above example, they would be stored in the + # for the relevant column entries; in the + # above example, they would be stored in the # # 2 # 55 # - # entries when justification is LEFT, and in the + # entries when justification is LEFT, and in the # # 111 # 4 @@ -977,399 +1056,408 @@ sub multicolumn_padding{ # # groupPadding # - # for each of the relevant column entries; in the - # above example, they would be stored in the + # for each of the relevant column entries; in the + # above example, they would be stored in the # # 2 # 55 # - # entries when justification is LEFT, and in the + # entries when justification is LEFT, and in the # # 111 # 4 # # (3) finally, account for the \multicolumn command itself; - # ensuring that we account for it being wider or narrower + # ensuring that we account for it being wider or narrower # than its spanning columns my $self = shift; # row loop my $rowCount = -1; foreach my $row (@cellStorage) { - $rowCount++; - - # column loop - my $j = -1; - foreach my $cell (@$row) { - $j++; - - # multicolumn entry - next unless (${$cell}{type} =~ m/(\d+)/); - - my $multiColumnSpan = $1; - - my $maxGroupingWidth = 0; - - # depending on the - # - # justification - # - # setting (left or right), we store the - # - # groupingWidth - # - # and groupPadding accordingly - my $justificationOffset = (${$self}{justification} eq "left" ? $j+$multiColumnSpan-1 : $j); - - # phase (1) - # phase (1) - # phase (1) - - # *inner* row loop - my $innerRowCount = -1; - foreach my $innerRow (@cellStorage) { - $innerRowCount++; - - # we only want to measure the *other* rows - next if($innerRowCount == $rowCount); - - # we will store the width of columns spanned by the multicolumn command - my $groupingWidth = 0; - - # *inner* column loop - for (my $innerJ = 0; $innerJ < $multiColumnSpan; $innerJ++) { - - # some entries should not be measured in the grouping width, - # for example - # - # \multicolumn{2}{c}{thing} & \\ - # 111 & 2 & 33333 \\ - # 4 & 55 & 66 \\ - # \multicolumn{2}{c}{a} & \\ - # - # ^^^^^^^^ - # |||||||| - # - # the second \multicolumn entry shouldn't be measured, and it will - # have had - # - # measureThis - # - # switched off during multicolumn_pre_check - - next if !${$cellStorage[$innerRowCount][$j+$innerJ]}{measureThis}; - - $groupingWidth += ${$cellStorage[$innerRowCount][$j+$innerJ]}{width}; - $groupingWidth += ${$cellStorage[$innerRowCount][$j+$innerJ]}{individualPadding}; - $groupingWidth += ${$cellStorage[$innerRowCount][$j+$innerJ]}{delimiterLength} if ($innerJ < $multiColumnSpan - 1); - } + $rowCount++; - # adjust for - # <spacesBeforeAmpersand> - # & - # <spacesEndAmpersand> - # note: - # we need to multiply this by the appropriate multicolumn - # spanning; in the above example: - # - # \multicolumn{2}{c}{thing} & \\ - # 111 & 2 & 33333 \\ - # 4 & 55 & 66 \\ + # column loop + my $j = -1; + foreach my $cell (@$row) { + $j++; + + # multicolumn entry + next unless ( ${$cell}{type} =~ m/(\d+)/ ); + + my $multiColumnSpan = $1; + + my $maxGroupingWidth = 0; + + # depending on the # - # we multiply by (2-1) = 1 because there is *1* ampersand - # underneath the multicolumn command + # justification # - # note: - # the & will have been accounted for in the above section using delimiterLength - - $groupingWidth += ($multiColumnSpan-1) - * - (${$self}{spacesBeforeAmpersand} + ${$self}{spacesAfterAmpersand}); - - # store the grouping width for the next phase - ${$cellStorage[$innerRowCount][$justificationOffset]}{groupingWidth} = $groupingWidth; - - # update the maximum grouping width - $maxGroupingWidth = max($maxGroupingWidth, $groupingWidth); - - } - - # phase (2) - # phase (2) - # phase (2) - - # now that the maxGroupingWidth has been established, loop back - # through and update groupingWidth for the appropriate cells - - # *inner* row loop - $innerRowCount = -1; - foreach my $innerRow (@cellStorage) { - $innerRowCount++; - - # we only want to make adjustment on the *other* rows - next if($innerRowCount == $rowCount); - - # it's possible that we have multicolumn commands that were *not* measured, - # and are *narrower* than the maxGroupingWidth, for example: + # setting (left or right), we store the # - # \multicolumn{3}{l}{aaaa} & \\ <------ this entry won't have been measured! - # $S_N$ & $=$ & $\SI{1000}{\kV\A}$ & $U_0$ & \\ - # \multicolumn{3}{l}{bbbbbbb} & \\ + # groupingWidth # - if( ${$cellStorage[$innerRowCount][$j]}{colSpan} ne "." - and ${$cellStorage[$innerRowCount][$j]}{colSpan} == $multiColumnSpan - and !${$cellStorage[$innerRowCount][$j]}{measureThis} - and $maxGroupingWidth > ${$cellStorage[$innerRowCount][$j]}{width} - and ${$cellStorage[$innerRowCount][$j]}{width} >= ${$cell}{width}) { - ${$cellStorage[$innerRowCount][$j]}{individualPadding} = 0; - ${$cellStorage[$innerRowCount][$j]}{groupPadding} = ($maxGroupingWidth - ${$cellStorage[$innerRowCount][$j]}{width}); + # and groupPadding accordingly + my $justificationOffset = ( ${$self}{justification} eq "left" ? $j + $multiColumnSpan - 1 : $j ); + + # phase (1) + # phase (1) + # phase (1) + + # *inner* row loop + my $innerRowCount = -1; + foreach my $innerRow (@cellStorage) { + $innerRowCount++; + + # we only want to measure the *other* rows + next if ( $innerRowCount == $rowCount ); + + # we will store the width of columns spanned by the multicolumn command + my $groupingWidth = 0; + + # *inner* column loop + for ( my $innerJ = 0; $innerJ < $multiColumnSpan; $innerJ++ ) { + + # some entries should not be measured in the grouping width, + # for example + # + # \multicolumn{2}{c}{thing} & \\ + # 111 & 2 & 33333 \\ + # 4 & 55 & 66 \\ + # \multicolumn{2}{c}{a} & \\ + # + # ^^^^^^^^ + # |||||||| + # + # the second \multicolumn entry shouldn't be measured, and it will + # have had + # + # measureThis + # + # switched off during multicolumn_pre_check + + next if !${ $cellStorage[$innerRowCount][ $j + $innerJ ] }{measureThis}; + + $groupingWidth += ${ $cellStorage[$innerRowCount][ $j + $innerJ ] }{width}; + $groupingWidth += ${ $cellStorage[$innerRowCount][ $j + $innerJ ] }{individualPadding}; + $groupingWidth += ${ $cellStorage[$innerRowCount][ $j + $innerJ ] }{delimiterLength} + if ( $innerJ < $multiColumnSpan - 1 ); + } + + # adjust for + # <spacesBeforeAmpersand> + # & + # <spacesEndAmpersand> + # note: + # we need to multiply this by the appropriate multicolumn + # spanning; in the above example: + # + # \multicolumn{2}{c}{thing} & \\ + # 111 & 2 & 33333 \\ + # 4 & 55 & 66 \\ + # + # we multiply by (2-1) = 1 because there is *1* ampersand + # underneath the multicolumn command + # + # note: + # the & will have been accounted for in the above section using delimiterLength + + $groupingWidth + += ( $multiColumnSpan - 1 ) * ( ${$self}{spacesBeforeAmpersand} + ${$self}{spacesAfterAmpersand} ); + + # store the grouping width for the next phase + ${ $cellStorage[$innerRowCount][$justificationOffset] }{groupingWidth} = $groupingWidth; + + # update the maximum grouping width + $maxGroupingWidth = max( $maxGroupingWidth, $groupingWidth ); + } - my $groupingWidth = ${$cellStorage[$innerRowCount][$justificationOffset]}{groupingWidth}; + # phase (2) + # phase (2) + # phase (2) - # phase (3) - # phase (3) - # phase (3) - - # there are two possible cases: - # - # (1) the \multicolumn statement is *WIDER* than its grouped columns, e.g.: - # - # \multicolumn{2}{c}{thing} & \\ - # 111 & 2 & 33333 \\ - # 4 & 55 & 66 \\ - # ^^^^^^^^^^^^^^^ - # ||||||||||||||| - # - # in this situation, we need to adjust each of the group paddings for the cells - # marked with an up arrow - # - # (2) the \multicolumn statement is *NARROWER* than its grouped columns, e.g.: - # - # || - # ** - # \multicolumn{2}{c}{thing} & \\ - # 111 & bbbbbbbbbbbbbbbbbbbbbb & 33333 \\ - # 4 & 55 & 66 \\ - # - # in this situation, we need to adjust the groupPadding of the multicolumn - # entry, which happens ***once the row loop has finished*** - # - if(${$cell}{width} > $maxGroupingWidth ){ - ${$cellStorage[$innerRowCount][$justificationOffset]}{groupPadding} = (${$cell}{width} - $maxGroupingWidth ); - } - } - - # case (2) from above when \multicolumn statement is *NARROWER* than its grouped columns - if(${$cell}{width} < $maxGroupingWidth ){ - ${$cell}{groupPadding} += ($maxGroupingWidth - ${$cell}{width}); - ${$cell}{individualPadding} = 0; - } - } + # now that the maxGroupingWidth has been established, loop back + # through and update groupingWidth for the appropriate cells + + # *inner* row loop + $innerRowCount = -1; + foreach my $innerRow (@cellStorage) { + $innerRowCount++; + + # we only want to make adjustment on the *other* rows + next if ( $innerRowCount == $rowCount ); + + # it's possible that we have multicolumn commands that were *not* measured, + # and are *narrower* than the maxGroupingWidth, for example: + # + # \multicolumn{3}{l}{aaaa} & \\ <------ this entry won't have been measured! + # $S_N$ & $=$ & $\SI{1000}{\kV\A}$ & $U_0$ & \\ + # \multicolumn{3}{l}{bbbbbbb} & \\ + # + if ( ${ $cellStorage[$innerRowCount][$j] }{colSpan} ne "." + and ${ $cellStorage[$innerRowCount][$j] }{colSpan} == $multiColumnSpan + and !${ $cellStorage[$innerRowCount][$j] }{measureThis} + and $maxGroupingWidth > ${ $cellStorage[$innerRowCount][$j] }{width} + and ${ $cellStorage[$innerRowCount][$j] }{width} >= ${$cell}{width} ) + { + ${ $cellStorage[$innerRowCount][$j] }{individualPadding} = 0; + ${ $cellStorage[$innerRowCount][$j] }{groupPadding} + = ( $maxGroupingWidth - ${ $cellStorage[$innerRowCount][$j] }{width} ); + } + + my $groupingWidth = ${ $cellStorage[$innerRowCount][$justificationOffset] }{groupingWidth}; + + # phase (3) + # phase (3) + # phase (3) + + # there are two possible cases: + # + # (1) the \multicolumn statement is *WIDER* than its grouped columns, e.g.: + # + # \multicolumn{2}{c}{thing} & \\ + # 111 & 2 & 33333 \\ + # 4 & 55 & 66 \\ + # ^^^^^^^^^^^^^^^ + # ||||||||||||||| + # + # in this situation, we need to adjust each of the group paddings for the cells + # marked with an up arrow + # + # (2) the \multicolumn statement is *NARROWER* than its grouped columns, e.g.: + # + # || + # ** + # \multicolumn{2}{c}{thing} & \\ + # 111 & bbbbbbbbbbbbbbbbbbbbbb & 33333 \\ + # 4 & 55 & 66 \\ + # + # in this situation, we need to adjust the groupPadding of the multicolumn + # entry, which happens ***once the row loop has finished*** + # + if ( ${$cell}{width} > $maxGroupingWidth ) { + ${ $cellStorage[$innerRowCount][$justificationOffset] }{groupPadding} + = ( ${$cell}{width} - $maxGroupingWidth ); + } + } + + # case (2) from above when \multicolumn statement is *NARROWER* than its grouped columns + if ( ${$cell}{width} < $maxGroupingWidth ) { + ${$cell}{groupPadding} += ( $maxGroupingWidth - ${$cell}{width} ); + ${$cell}{individualPadding} = 0; + } + } } } sub multicolumn_post_check { - # PURPOSE: - # ensure that multiple multicolumn commands are - # handled appropriately - # - # example 1 - # - # \multicolumn{2}{c}{thing} & aaa & bbb \\ - # 111 & 2 & 33333 & \\ - # 4 & 55 & 66 & \\ - # \multicolumn{3}{c}{a} & \\ - # - # ^^^^^^^^ - # |||||||| - # - # the second multicolumn command needs to have its group padding - # accounted for. - # - # *Note* this will not have been done previously, as - # this second multicolumn command will have had its type changed to - # X, because it spans 3 columns, and there is a cell within its - # column that spans *less than 3 columns* - my $self = shift; - - # row loop - my $rowCount = -1; - foreach my $row (@cellStorage) { - $rowCount++; - - # column loop - my $j = -1; - foreach my $cell (@$row) { - $j++; - - # we only need to account for X-type columns, with an integer colSpan - next unless (${$cell}{type} eq "X" and ${$cell}{colSpan} =~ m/(\d+)/); - - # multicolumn entry - my $multiColumnSpan = $1; - - # we store the maximum grouping width - my $maxGroupingWidth = 0; - - # *inner* row loop - my $innerRowCount = -1; - foreach my $innerRow (@cellStorage) { - $innerRowCount++; - - # we only want to measure the *other* rows - next if($innerRowCount == $rowCount); - - # we will store the width of columns spanned by the multicolumn command - my $groupingWidth = 0; - - # we need to keep track of the number of ampersands encountered; - # - # for example: - # - # \multicolumn{2}{c}{thing} & aaa & bbb \\ - # 111 & 2 & 33333 & \\ - # 4 & 55 & 66 & \\ - # \multicolumn{3}{c}{a} & \\ <!----- focus on the multicolumn entry in this row - # - # focusing on the final multicolumn entry (spanning 3 columns), - # when we loop back through the rows, we will encounter: - # - # row 1: one ampersand - # - # \multicolumn{2}{c}{thing} & aaa ... - # - # row 2: two ampersands - # - # 111 & 2 & 33333 ... - # - # row 3: two ampersands - # - # 4 & 55 & 66 ... - # - # note: we start the counter at -1, because the count of ampersands - # is always one behind the cell count; for example, looking - # at row 3 in the above, in the above, in cell 1 (entry: 4) - # we have 0 ampersands, in cell 2 (entry: 55) we now have 1 ampersands, etc - my $ampersandsEncountered = -1; + + # PURPOSE: + # ensure that multiple multicolumn commands are + # handled appropriately + # + # example 1 + # + # \multicolumn{2}{c}{thing} & aaa & bbb \\ + # 111 & 2 & 33333 & \\ + # 4 & 55 & 66 & \\ + # \multicolumn{3}{c}{a} & \\ + # + # ^^^^^^^^ + # |||||||| + # + # the second multicolumn command needs to have its group padding + # accounted for. + # + # *Note* this will not have been done previously, as + # this second multicolumn command will have had its type changed to + # X, because it spans 3 columns, and there is a cell within its + # column that spans *less than 3 columns* + my $self = shift; + + # row loop + my $rowCount = -1; + foreach my $row (@cellStorage) { + $rowCount++; # column loop - my @dumRow = @$innerRow; - foreach (my $innerJ = 0; $innerJ <= $#dumRow; $innerJ++){ - - # exit the loop if we've reached the multiColumn spanning width - last if($innerJ >= ($multiColumnSpan)); - - # don't include '*' or '-' cell types in the calculations - my $type = ${$cellStorage[$innerRowCount][$j+$innerJ]}{type}; - next if($type eq "*" or $type eq "-"); - - # update the grouping width - $groupingWidth += ${$cellStorage[$innerRowCount][$j+$innerJ]}{width}; - $groupingWidth += ${$cellStorage[$innerRowCount][$j+$innerJ]}{individualPadding}; - - # update the number of & encountered - $ampersandsEncountered++; - $groupingWidth += ${$cellStorage[$innerRowCount][$j+$innerJ]}{delimiterLength} if ($ampersandsEncountered>0); - - # and adjust the column count, if necessary; in the above example - # - # \multicolumn{2}{c}{thing} & aaa & bbb \\ - # 111 & 2 & 33333 & \\ - # 4 & 55 & 66 & \\ - # \multicolumn{3}{c}{a} & \\ <!----- focus on the multicolumn entry in this row - # - # the *first entry* \multicolumn{2}{c}{thing} spans 2 columns, so - # we need to move the column count along accordingly - - if(${$cellStorage[$innerRowCount][$j+$innerJ]}{colSpan} =~ m/(\d+)/){ - $innerJ += $1-1; - } - + my $j = -1; + foreach my $cell (@$row) { + $j++; + + # we only need to account for X-type columns, with an integer colSpan + next unless ( ${$cell}{type} eq "X" and ${$cell}{colSpan} =~ m/(\d+)/ ); + + # multicolumn entry + my $multiColumnSpan = $1; + + # we store the maximum grouping width + my $maxGroupingWidth = 0; + + # *inner* row loop + my $innerRowCount = -1; + foreach my $innerRow (@cellStorage) { + $innerRowCount++; + + # we only want to measure the *other* rows + next if ( $innerRowCount == $rowCount ); + + # we will store the width of columns spanned by the multicolumn command + my $groupingWidth = 0; + + # we need to keep track of the number of ampersands encountered; + # + # for example: + # + # \multicolumn{2}{c}{thing} & aaa & bbb \\ + # 111 & 2 & 33333 & \\ + # 4 & 55 & 66 & \\ + # \multicolumn{3}{c}{a} & \\ <!----- focus on the multicolumn entry in this row + # + # focusing on the final multicolumn entry (spanning 3 columns), + # when we loop back through the rows, we will encounter: + # + # row 1: one ampersand + # + # \multicolumn{2}{c}{thing} & aaa ... + # + # row 2: two ampersands + # + # 111 & 2 & 33333 ... + # + # row 3: two ampersands + # + # 4 & 55 & 66 ... + # + # note: we start the counter at -1, because the count of ampersands + # is always one behind the cell count; for example, looking + # at row 3 in the above, in the above, in cell 1 (entry: 4) + # we have 0 ampersands, in cell 2 (entry: 55) we now have 1 ampersands, etc + my $ampersandsEncountered = -1; + + # column loop + my @dumRow = @$innerRow; + foreach ( my $innerJ = 0; $innerJ <= $#dumRow; $innerJ++ ) { + + # exit the loop if we've reached the multiColumn spanning width + last if ( $innerJ >= ($multiColumnSpan) ); + + # don't include '*' or '-' cell types in the calculations + my $type = ${ $cellStorage[$innerRowCount][ $j + $innerJ ] }{type}; + next if ( $type eq "*" or $type eq "-" ); + + # update the grouping width + $groupingWidth += ${ $cellStorage[$innerRowCount][ $j + $innerJ ] }{width}; + $groupingWidth += ${ $cellStorage[$innerRowCount][ $j + $innerJ ] }{individualPadding}; + + # update the number of & encountered + $ampersandsEncountered++; + $groupingWidth += ${ $cellStorage[$innerRowCount][ $j + $innerJ ] }{delimiterLength} + if ( $ampersandsEncountered > 0 ); + + # and adjust the column count, if necessary; in the above example + # + # \multicolumn{2}{c}{thing} & aaa & bbb \\ + # 111 & 2 & 33333 & \\ + # 4 & 55 & 66 & \\ + # \multicolumn{3}{c}{a} & \\ <!----- focus on the multicolumn entry in this row + # + # the *first entry* \multicolumn{2}{c}{thing} spans 2 columns, so + # we need to move the column count along accordingly + + if ( ${ $cellStorage[$innerRowCount][ $j + $innerJ ] }{colSpan} =~ m/(\d+)/ ) { + $innerJ += $1 - 1; + } + + } + + # adjust for + # <spacesBeforeAmpersand> + # & + # <spacesEndAmpersand> + # note: + # we need to multiply this by the appropriate + # number of *ampersandsEncountered* + # + # \multicolumn{2}{c}{thing} & \\ + # 111 & 2 & 33333 \\ + # 4 & 55 & 66 \\ + + $groupingWidth + += $ampersandsEncountered * ( ${$self}{spacesBeforeAmpersand} + ${$self}{spacesAfterAmpersand} ); + + # update the maximum grouping width + $maxGroupingWidth = max( $maxGroupingWidth, $groupingWidth ); + } + + ${$cell}{individualPadding} = 0; + + # there are cases where the + # + # maxGroupingWidth + # + # is *less than* the cell width, for example: + # + # \multicolumn{4}{|c|}{\textbf{Search Results}} \\ <!------ the width of this multicolumn entry + # 1 & D7 & R & \\ is larger than maxGroupingWidth + # 2 & D2 & R & \\ + # \multicolumn{3}{|c|}{\textbf{Avg}} & \\ + # + ${$cell}{groupPadding} = max( 0, $maxGroupingWidth - ${$cell}{width} ); } - - # adjust for - # <spacesBeforeAmpersand> - # & - # <spacesEndAmpersand> - # note: - # we need to multiply this by the appropriate - # number of *ampersandsEncountered* - # - # \multicolumn{2}{c}{thing} & \\ - # 111 & 2 & 33333 \\ - # 4 & 55 & 66 \\ - - $groupingWidth += $ampersandsEncountered - * - (${$self}{spacesBeforeAmpersand} + ${$self}{spacesAfterAmpersand}); - - # update the maximum grouping width - $maxGroupingWidth = max($maxGroupingWidth, $groupingWidth); - } - - ${$cell}{individualPadding} = 0; - - # there are cases where the - # - # maxGroupingWidth - # - # is *less than* the cell width, for example: - # - # \multicolumn{4}{|c|}{\textbf{Search Results}} \\ <!------ the width of this multicolumn entry - # 1 & D7 & R & \\ is larger than maxGroupingWidth - # 2 & D2 & R & \\ - # \multicolumn{3}{|c|}{\textbf{Avg}} & \\ - # - ${$cell}{groupPadding} = max(0,$maxGroupingWidth - ${$cell}{width}); - } } } -sub pretty_print_cell_info{ - - my $thingToPrint = (defined $_[0] ? $_[0] : "entry"); +sub pretty_print_cell_info { - $logger->trace("*cell information: $thingToPrint"); + my $thingToPrint = ( defined $_[0] ? $_[0] : "entry" ); - $logger->trace("minimum multi col span: ".join(",",@minMultiColSpan)) if(@minMultiColSpan); + $logger->trace("*cell information: $thingToPrint"); - foreach my $row (@cellStorage) { - my $tmpLogFileLine = q(); - foreach my $cell (@$row) { - $tmpLogFileLine .= ${$cell}{$thingToPrint}."\t"; + $logger->trace( "minimum multi col span: " . join( ",", @minMultiColSpan ) ) if (@minMultiColSpan); + + foreach my $row (@cellStorage) { + my $tmpLogFileLine = q(); + foreach my $cell (@$row) { + $tmpLogFileLine .= ${$cell}{$thingToPrint} . "\t"; + } + $logger->trace( ' ' . $tmpLogFileLine ) if ($is_t_switch_active); } - $logger->trace(' '. $tmpLogFileLine) if($is_t_switch_active); - } - if($thingToPrint eq "type"){ - $logger->trace("*key to types:"); - $logger->trace("\tX\tbasic cell, will be measured and aligned"); - $logger->trace("\t*\t will not be measured, and no ampersand"); - $logger->trace("\t-\t phantom/blank cell for gaps"); - $logger->trace("\t[0-9]\tmulticolumn cell, spanning multiple columns"); - } + if ( $thingToPrint eq "type" ) { + $logger->trace("*key to types:"); + $logger->trace("\tX\tbasic cell, will be measured and aligned"); + $logger->trace("\t*\t will not be measured, and no ampersand"); + $logger->trace("\t-\t phantom/blank cell for gaps"); + $logger->trace("\t[0-9]\tmulticolumn cell, spanning multiple columns"); + } } -sub double_back_slash_else{ +sub double_back_slash_else { my $self = shift; # check for existence of \\ statement, and associated line break information $self->check_for_else_statement( - # else name regexp - elseNameRegExp=>qr/${${$mainSettings{fineTuning}}{modifyLineBreaks}}{doubleBackSlash}/, - # else statements name: note that DBS stands for 'Double Back Slash' - ElseStartsOnOwnLine=>"DBSStartsOnOwnLine", - # end statements - ElseFinishesWithLineBreak=>"DBSFinishesWithLineBreak", - # for the YAML settings storage - storageNameAppend=>"DBS", - # logfile information - logName=>"double-back-slash-block (for align at ampersand, see lookForAlignDelims)", - ); + + # else name regexp + elseNameRegExp => qr/${${$mainSettings{fineTuning}}{modifyLineBreaks}}{doubleBackSlash}/, + + # else statements name: note that DBS stands for 'Double Back Slash' + ElseStartsOnOwnLine => "DBSStartsOnOwnLine", + + # end statements + ElseFinishesWithLineBreak => "DBSFinishesWithLineBreak", + + # for the YAML settings storage + storageNameAppend => "DBS", + + # logfile information + logName => "double-back-slash-block (for align at ampersand, see lookForAlignDelims)", + ); } # possible hidden children, see test-cases/alignment/issue-162.tex and friends @@ -1392,53 +1480,56 @@ sub double_back_slash_else{ # measure CELL width that has hidden children # # A & =\begin{array}{cc} -# BBB & CCC \\ -# E & F -# \end{array} \\ +# BBB & CCC \\ +# E & F +# \end{array} \\ # # ^^^^^^^^^^^^^^^^^^ # |||||||||||||||||| # # Cell # -sub hidden_child_cell_row_width{ +sub hidden_child_cell_row_width { my $self = shift; - my ($tmpCellEntry, $rowCounter, $columnCounter) = @_; + my ( $tmpCellEntry, $rowCounter, $columnCounter ) = @_; - for my $hiddenChildToMeasure (@{${$self}{measureHiddenChildren}}){ - if($tmpCellEntry =~m/.*?$hiddenChildToMeasure/s and defined $familyTree{$hiddenChildToMeasure}{bodyForMeasure}){ - $tmpCellEntry =~ s/$hiddenChildToMeasure/$familyTree{$hiddenChildToMeasure}{bodyForMeasure}/s; - } + for my $hiddenChildToMeasure ( @{ ${$self}{measureHiddenChildren} } ) { + if ( $tmpCellEntry =~ m/.*?$hiddenChildToMeasure/s + and defined $familyTree{$hiddenChildToMeasure}{bodyForMeasure} ) + { + $tmpCellEntry =~ s/$hiddenChildToMeasure/$familyTree{$hiddenChildToMeasure}{bodyForMeasure}/s; + } } - if ($tmpCellEntry =~ m/$tokens{verbatim}/){ - # - # verbatim example: - # - # \begin{tabular}{ll} - # Testing & Line 1 \\ - # Testing & Line 2 \\ - # Testing & Line 3 \verb|X| \\ - # Testing & Line 4 \\ - # \end{tabular} - while( my ($verbatimID,$child)= each %verbatimStorage){ - if($tmpCellEntry =~m/.*?$verbatimID/s){ - $tmpCellEntry =~ s/$verbatimID/${$child}{begin}${$child}{body}${$child}{end}/s; - } - } + if ( $tmpCellEntry =~ m/$tokens{verbatim}/ ) { + # + # verbatim example: + # + # \begin{tabular}{ll} + # Testing & Line 1 \\ + # Testing & Line 2 \\ + # Testing & Line 3 \verb|X| \\ + # Testing & Line 4 \\ + # \end{tabular} + while ( my ( $verbatimID, $child ) = each %verbatimStorage ) { + if ( $tmpCellEntry =~ m/.*?$verbatimID/s ) { + $tmpCellEntry =~ s/$verbatimID/${$child}{begin}${$child}{body}${$child}{end}/s; + } + } } my $bodyLineBreaks = 0; - $bodyLineBreaks++ while($tmpCellEntry =~ m/\R/sg); - if($bodyLineBreaks>0){ + $bodyLineBreaks++ while ( $tmpCellEntry =~ m/\R/sg ); + if ( $bodyLineBreaks > 0 ) { my $maxRowWidthWithinCell = 0; - foreach(split("\n",$tmpCellEntry)){ - my $currentRowWidth = &get_column_width($_); - $maxRowWidthWithinCell = $currentRowWidth if ($currentRowWidth > $maxRowWidthWithinCell ); + foreach ( split( "\n", $tmpCellEntry ) ) { + my $currentRowWidth = &get_column_width($_); + $maxRowWidthWithinCell = $currentRowWidth if ( $currentRowWidth > $maxRowWidthWithinCell ); } - ${$cellStorage[$rowCounter][$columnCounter]}{width} = $maxRowWidthWithinCell; - } else { - ${$cellStorage[$rowCounter][$columnCounter]}{width} = &get_column_width($tmpCellEntry); + ${ $cellStorage[$rowCounter][$columnCounter] }{width} = $maxRowWidthWithinCell; + } + else { + ${ $cellStorage[$rowCounter][$columnCounter] }{width} = &get_column_width($tmpCellEntry); } } @@ -1447,19 +1538,19 @@ sub hidden_child_cell_row_width{ # measure ROW width that has hidden children # # A & =\begin{array}{cc} -# BBB & CCC \\ -# E & F -# \end{array} \\ +# BBB & CCC \\ +# E & F +# \end{array} \\ # # ^^^^^^^^^^^^^^^^^^^^^^ # |||||||||||||||||||||| # # row # -sub hidden_child_row_width{ +sub hidden_child_row_width { my $self = shift; - my ($tmpRow,$rowCount,$rowWidth) = @_; + my ( $tmpRow, $rowCount, $rowWidth ) = @_; # some alignment blocks have the 'begin' statement on the opening line: # @@ -1472,47 +1563,53 @@ sub hidden_child_row_width{ # \end{align*} # my $lengthOfBegin = 0; - if (!${${$self}{linebreaksAtEnd}}{begin} - and ${$cellStorage[0][0]}{type} eq "X" - and ${$cellStorage[0][0]}{measureThis}){ + if ( !${ ${$self}{linebreaksAtEnd} }{begin} + and ${ $cellStorage[0][0] }{type} eq "X" + and ${ $cellStorage[0][0] }{measureThis} ) + { my $beginToMeasure = ${$self}{begin}; - if( (${$self}{begin} eq '{' | ${$self}{begin} eq '[') and ${$self}{parentBegin}){ - $beginToMeasure = ${$self}{parentBegin}."{"; + if ( ( ${$self}{begin} eq '{' | ${$self}{begin} eq '[' ) and ${$self}{parentBegin} ) { + $beginToMeasure = ${$self}{parentBegin} . "{"; } $lengthOfBegin = &get_column_width($beginToMeasure); - $tmpRow = $beginToMeasure.$tmpRow if $rowCount == 0; + $tmpRow = $beginToMeasure . $tmpRow if $rowCount == 0; } - if ($tmpRow =~m/.*?$tokens{beginOfToken}/s){ + if ( $tmpRow =~ m/.*?$tokens{beginOfToken}/s ) { + + $tmpRow = ( "." x $lengthOfBegin ) . $tmpRow; + + for my $hiddenChildToMeasure ( @{ ${$self}{measureHiddenChildren} } ) { + if ( $tmpRow =~ m/(^.*)?$hiddenChildToMeasure/m + and defined $familyTree{$hiddenChildToMeasure}{bodyForMeasure} ) + { + my $partBeforeId = $1; + my $lengthPartBeforeId = &get_column_width($partBeforeId); + + foreach ( @{ $familyTree{$hiddenChildToMeasure}{ancestors} } ) { + if ( ${$_}{ancestorID} eq ${$self}{id} ) { + if ( $lengthOfBegin > 0 ) { + ${$_}{ancestorIndentation} = ( " " x ($lengthPartBeforeId) ); + } + else { + ${$_}{ancestorIndentation} = ${$_}{ancestorIndentation} . ( " " x ($lengthPartBeforeId) ); + } + } + } + my $tmpBodyToMeasure = join( + "\n" . ( "." x ($lengthPartBeforeId) ), + split( "\n", $familyTree{$hiddenChildToMeasure}{bodyForMeasure} ) + ); - $tmpRow = ("."x$lengthOfBegin).$tmpRow; + # remove trailing \\ + $tmpBodyToMeasure =~ s/(\\\\\h*$)//mg; - for my $hiddenChildToMeasure (@{${$self}{measureHiddenChildren}}){ - if($tmpRow=~m/(^.*)?$hiddenChildToMeasure/m and defined $familyTree{$hiddenChildToMeasure}{bodyForMeasure}){ - my $partBeforeId = $1; - my $lengthPartBeforeId = &get_column_width($partBeforeId); + $tmpRow =~ s/$hiddenChildToMeasure/$tmpBodyToMeasure/s; + } + } - foreach (@{$familyTree{$hiddenChildToMeasure}{ancestors}}){ - if (${$_}{ancestorID} eq ${$self}{id}){ - if($lengthOfBegin>0){ - ${$_}{ancestorIndentation} = (" " x ($lengthPartBeforeId)); - } else { - ${$_}{ancestorIndentation} = ${$_}{ancestorIndentation}.(" " x ($lengthPartBeforeId)); - } - } - } - my $tmpBodyToMeasure = join( "\n".("."x($lengthPartBeforeId)), - split("\n",$familyTree{$hiddenChildToMeasure}{bodyForMeasure})); - - # remove trailing \\ - $tmpBodyToMeasure =~ s/(\\\\\h*$)//mg; - - $tmpRow =~ s/$hiddenChildToMeasure/$tmpBodyToMeasure/s; - } - } - - if ($tmpRow =~ m/$tokens{verbatim}/){ + if ( $tmpRow =~ m/$tokens{verbatim}/ ) { # # verbatim example: # @@ -1522,38 +1619,42 @@ sub hidden_child_row_width{ # Testing & Line 3 \verb|X| \\ # Testing & Line 4 \\ # \end{tabular} - while( my ($verbatimID,$child)= each %verbatimStorage){ - if($tmpRow =~m/.*?$verbatimID/s){ - $tmpRow =~ s/$verbatimID/${$child}{begin}${$child}{body}${$child}{end}/s; - } + while ( my ( $verbatimID, $child ) = each %verbatimStorage ) { + if ( $tmpRow =~ m/.*?$verbatimID/s ) { + $tmpRow =~ s/$verbatimID/${$child}{begin}${$child}{body}${$child}{end}/s; + } + } + } + + my $bodyLineBreaks = 0; + $bodyLineBreaks++ while ( $tmpRow =~ m/\R/sg ); + if ( $bodyLineBreaks > 0 ) { + my $maxRowWidth = 0; + + foreach ( split( "\n", $tmpRow ) ) { + my $currentRowWidth = &get_column_width($_); + $maxRowWidth = $currentRowWidth if ( $currentRowWidth > $maxRowWidth ); } - } - - my $bodyLineBreaks = 0; - $bodyLineBreaks++ while($tmpRow =~ m/\R/sg); - if($bodyLineBreaks>0){ - my $maxRowWidth = 0; - - foreach(split("\n",$tmpRow)){ - my $currentRowWidth = &get_column_width($_); - $maxRowWidth = $currentRowWidth if ($currentRowWidth > $maxRowWidth ); - } - $rowWidth = $maxRowWidth; - } else { - $rowWidth = &get_column_width($tmpRow); - } - } elsif (!${${$self}{linebreaksAtEnd}}{begin} - and ${$cellStorage[0][0]}{type} eq "X" - and ${$cellStorage[0][0]}{measureThis}){ - $rowWidth = &get_column_width($tmpRow); + $rowWidth = $maxRowWidth; } + else { + $rowWidth = &get_column_width($tmpRow); + } + } + elsif (!${ ${$self}{linebreaksAtEnd} }{begin} + and ${ $cellStorage[0][0] }{type} eq "X" + and ${ $cellStorage[0][0] }{measureThis} ) + { + $rowWidth = &get_column_width($tmpRow); + } + + # possibly draw ruler to log file + &draw_ruler_to_logfile( $tmpRow, $rowWidth ) if ($is_t_switch_active); + return $rowWidth; +} - # possibly draw ruler to log file - &draw_ruler_to_logfile($tmpRow,$rowWidth) if ($is_t_switch_active); - return $rowWidth; -} +sub draw_ruler_to_logfile { -sub draw_ruler_to_logfile{ # draw a ruler to the log file, useful for debugging # # example: @@ -1561,33 +1662,33 @@ sub draw_ruler_to_logfile{ # ----|----|----|----|----|----|----|----|----|----|----|----|----|----| # 5 10 15 20 25 30 35 40 45 50 55 60 65 70 # - - my ($tmpRow,$maxRowWidth) = @_; + + my ( $tmpRow, $maxRowWidth ) = @_; $logger->trace("*tmpRow:"); - foreach(split("\n",$tmpRow)){ - my $currentRowWidth = &get_column_width($_); - $logger->trace("$_ \t(length: $currentRowWidth)"); + foreach ( split( "\n", $tmpRow ) ) { + my $currentRowWidth = &get_column_width($_); + $logger->trace("$_ \t(length: $currentRowWidth)"); } - my $rulerMax = int($maxRowWidth/10 +1.5 )*10; - $logger->trace(("----|"x(int($rulerMax/5)))); + my $rulerMax = int( $maxRowWidth / 10 + 1.5 ) * 10; + $logger->trace( ( "----|" x ( int( $rulerMax / 5 ) ) ) ); my $ruler = q(); - for (my $i=1;$i<=$rulerMax/5;$i++){ $ruler .= " ".$i*5 }; + for ( my $i = 1; $i <= $rulerMax / 5; $i++ ) { $ruler .= " " . $i * 5 } $logger->trace($ruler); } -sub get_column_width{ +sub get_column_width { my $stringToBeMeasured = $_[0]; # default length measurement # credit/reference: https://perldoc.perl.org/perlunicook#%E2%84%9E-33:-String-length-in-graphemes - unless ($switches{GCString}){ + unless ( $switches{GCString} ) { my $count = 0; - while ($stringToBeMeasured =~ /\X/g) { $count++ } + while ( $stringToBeMeasured =~ /\X/g ) { $count++ } return $count; } diff --git a/Master/texmf-dist/scripts/latexindent/LatexIndent/Arguments.pm b/Master/texmf-dist/scripts/latexindent/LatexIndent/Arguments.pm index 35ea03a63e9..e70fd57fb51 100644 --- a/Master/texmf-dist/scripts/latexindent/LatexIndent/Arguments.pm +++ b/Master/texmf-dist/scripts/latexindent/LatexIndent/Arguments.pm @@ -1,4 +1,5 @@ package LatexIndent::Arguments; + # 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 @@ -23,28 +24,30 @@ use LatexIndent::GetYamlSettings qw/%mainSettings/; use LatexIndent::LogFile qw/$logger/; use Data::Dumper; use Exporter qw/import/; -our @ISA = "LatexIndent::Document"; # class inheritance, Programming Perl, pg 321 -our @EXPORT_OK = qw/get_arguments_regexp find_opt_mand_arguments construct_arguments_regexp $optAndMandRegExp comma_else/; +our @ISA = "LatexIndent::Document"; # class inheritance, Programming Perl, pg 321 +our @EXPORT_OK + = qw/get_arguments_regexp find_opt_mand_arguments construct_arguments_regexp $optAndMandRegExp comma_else/; our $ArgumentCounter; -our $optAndMandRegExp; -our $optAndMandRegExpWithLineBreaks; +our $optAndMandRegExp; +our $optAndMandRegExpWithLineBreaks; -sub construct_arguments_regexp{ +sub construct_arguments_regexp { my $self = shift; $optAndMandRegExp = $self->get_arguments_regexp; - $optAndMandRegExpWithLineBreaks = $self->get_arguments_regexp(mode=>"lineBreaksAtEnd"); + $optAndMandRegExpWithLineBreaks = $self->get_arguments_regexp( mode => "lineBreaksAtEnd" ); } -sub indent{ +sub indent { my $self = shift; - ${$self}{body} =~ s/\R$//s if ($is_m_switch_active and ${$self}{IDFollowedImmediatelyByLineBreak}); - $logger->trace("*Arguments object doesn't receive any direct indentation, but its children will...") if $is_t_switch_active; + ${$self}{body} =~ s/\R$//s if ( $is_m_switch_active and ${$self}{IDFollowedImmediatelyByLineBreak} ); + $logger->trace("*Arguments object doesn't receive any direct indentation, but its children will...") + if $is_t_switch_active; return; } -sub find_opt_mand_arguments{ +sub find_opt_mand_arguments { my $self = shift; $logger->trace("*Searching ${$self}{name} for optional and mandatory arguments") if $is_t_switch_active; @@ -52,53 +55,64 @@ sub find_opt_mand_arguments{ # blank line token my $blankLineToken = $tokens{blanklines}; - # the command object allows () - my $objectDependentOptAndMandRegExp = (defined ${$self}{optAndMandArgsRegExp} ? ${$self}{optAndMandArgsRegExp} : $optAndMandRegExpWithLineBreaks); + # the command object allows () + my $objectDependentOptAndMandRegExp + = ( defined ${$self}{optAndMandArgsRegExp} ? ${$self}{optAndMandArgsRegExp} : $optAndMandRegExpWithLineBreaks ); - if(${$self}{body} =~ m/^$objectDependentOptAndMandRegExp\h*($trailingCommentRegExp)?/){ - $logger->trace("Optional/Mandatory arguments".(${$mainSettings{commandCodeBlocks}}{roundParenthesesAllowed}?" (possibly round Parentheses)":q())." found in ${$self}{name}: $1") if $is_t_switch_active; + if ( ${$self}{body} =~ m/^$objectDependentOptAndMandRegExp\h*($trailingCommentRegExp)?/ ) { + $logger->trace( + "Optional/Mandatory arguments" + . ( + ${ $mainSettings{commandCodeBlocks} }{roundParenthesesAllowed} ? " (possibly round Parentheses)" : q() + ) + . " found in ${$self}{name}: $1" + ) if $is_t_switch_active; # create a new Arguments object # The arguments object is a little different to most # other objects, as it is created purely for its children, - # so some of the properties common to other objects, such + # so some of the properties common to other objects, such # as environment, ifelsefi, etc do not exist for Arguments; # they will, however, exist for its children: OptionalArgument, MandatoryArgument - my $arguments = LatexIndent::Arguments->new(begin=>"", - name=>${$self}{name}.":arguments", - parent=>${$self}{name}, - body=>$1, - linebreaksAtEnd=>{ - end=>$2?1:0, - }, - end=>"", - regexp=>$objectDependentOptAndMandRegExp, - endImmediatelyFollowedByComment=>$2?0:($3?1:0), - ); + my $arguments = LatexIndent::Arguments->new( + begin => "", + name => ${$self}{name} . ":arguments", + parent => ${$self}{name}, + body => $1, + linebreaksAtEnd => { end => $2 ? 1 : 0, }, + end => "", + regexp => $objectDependentOptAndMandRegExp, + endImmediatelyFollowedByComment => $2 ? 0 : ( $3 ? 1 : 0 ), + ); # give unique id $arguments->create_unique_id; - + # text wrapping can make the ID split across lines ${$arguments}{idRegExp} = ${$arguments}{id}; - if($is_m_switch_active and ${$mainSettings{modifyLineBreaks}{textWrapOptions}}{huge} ne "overflow"){ - my $IDwithLineBreaks = join("\\R?\\h*",split(//,${$arguments}{id})); - ${$arguments}{idRegExp} = qr/$IDwithLineBreaks/s; + if ( $is_m_switch_active and ${ $mainSettings{modifyLineBreaks}{textWrapOptions} }{huge} ne "overflow" ) { + my $IDwithLineBreaks = join( "\\R?\\h*", split( //, ${$arguments}{id} ) ); + ${$arguments}{idRegExp} = qr/$IDwithLineBreaks/s; } # determine which comes first, optional or mandatory - if(${$arguments}{body} =~ m/.*?((?<!\\)\{|\[)/s){ + if ( ${$arguments}{body} =~ m/.*?((?<!\\)\{|\[)/s ) { + + if ( $1 eq "\[" ) { + $logger->trace("Searching for optional arguments, and then mandatory (optional found first)") + if $is_t_switch_active; - if($1 eq "\["){ - $logger->trace("Searching for optional arguments, and then mandatory (optional found first)") if $is_t_switch_active; # look for optional arguments $arguments->find_optional_arguments; # look for mandatory arguments $arguments->find_mandatory_arguments; - } else { - $logger->trace("Searching for mandatory arguments, and then optional (mandatory found first)") if $is_t_switch_active; + } + else { + $logger->trace("Searching for mandatory arguments, and then optional (mandatory found first)") + if $is_t_switch_active; + # look for mandatory arguments $arguments->find_mandatory_arguments; @@ -108,35 +122,45 @@ sub find_opt_mand_arguments{ # it's possible not to have any mandatory or optional arguments, see # https://github.com/cmhughes/latexindent.pl/issues/123 - if( !(defined ${$arguments}{children}) ){ - $logger->trace("No optional or mandatory arguments found; searching for matching round parenthesis") if $is_t_switch_active; + if ( !( defined ${$arguments}{children} ) ) { + $logger->trace("No optional or mandatory arguments found; searching for matching round parenthesis") + if $is_t_switch_active; $arguments->find_round_brackets; } - } else { - $logger->trace("Searching for round brackets ONLY") if $is_t_switch_active; - # look for round brackets - $arguments->find_round_brackets; + } + else { + $logger->trace("Searching for round brackets ONLY") if $is_t_switch_active; + + # look for round brackets + $arguments->find_round_brackets; } # we need to store the parent begin in each of the arguments, for example, see # test-cases/texexchange/112343-morbusg.tex # which has an alignment delimiter in the first line - if (${$self}{lookForAlignDelims}){ - foreach (@{${$arguments}{children}}){ + if ( ${$self}{lookForAlignDelims} ) { + foreach ( @{ ${$arguments}{children} } ) { ${$_}{parentBegin} = ${$self}{begin}; } } - # examine *first* child - # situation: parent BodyStartsOnOwnLine >= 1, but first child has BeginStartsOnOwnLine == 0 || BeginStartsOnOwnLine == undef - # problem: the *body* of parent actually starts after the arguments - # solution: remove the linebreak at the end of the begin statement of the parent - if(defined ${$self}{BodyStartsOnOwnLine} and ${$self}{BodyStartsOnOwnLine}>=1){ - if( !(defined ${${${$arguments}{children}}[0]}{BeginStartsOnOwnLine} and ${${${$arguments}{children}}[0]}{BeginStartsOnOwnLine}>=1) - and ${$self}{body} !~ m/^$blankLineToken/){ - my $BodyStringLogFile = ${$self}{aliases}{BodyStartsOnOwnLine}||"BodyStartsOnOwnLine"; - my $BeginStringLogFile = ${${${$arguments}{children}}[0]}{aliases}{BeginStartsOnOwnLine}||"BeginStartsOnOwnLine"; - $logger->trace("$BodyStringLogFile = 1 (in ${$self}{name}), but first argument should not begin on its own line (see $BeginStringLogFile)") if $is_t_switch_active; +# examine *first* child +# situation: parent BodyStartsOnOwnLine >= 1, but first child has BeginStartsOnOwnLine == 0 || BeginStartsOnOwnLine == undef +# problem: the *body* of parent actually starts after the arguments +# solution: remove the linebreak at the end of the begin statement of the parent + if ( defined ${$self}{BodyStartsOnOwnLine} and ${$self}{BodyStartsOnOwnLine} >= 1 ) { + if (!( defined ${ ${ ${$arguments}{children} }[0] }{BeginStartsOnOwnLine} + and ${ ${ ${$arguments}{children} }[0] }{BeginStartsOnOwnLine} >= 1 + ) + and ${$self}{body} !~ m/^$blankLineToken/ + ) + { + my $BodyStringLogFile = ${$self}{aliases}{BodyStartsOnOwnLine} || "BodyStartsOnOwnLine"; + my $BeginStringLogFile + = ${ ${ ${$arguments}{children} }[0] }{aliases}{BeginStartsOnOwnLine} || "BeginStartsOnOwnLine"; + $logger->trace( + "$BodyStringLogFile = 1 (in ${$self}{name}), but first argument should not begin on its own line (see $BeginStringLogFile)" + ) if $is_t_switch_active; $logger->trace("Removing line breaks at the end of ${$self}{begin}") if $is_t_switch_active; ${$self}{begin} =~ s/\R*$//s; ${$self}{linebreaksAtEnd}{begin} = 0; @@ -145,41 +169,57 @@ sub find_opt_mand_arguments{ # situation: preserveBlankLines is active, so the body may well begin with a blank line token # which means that ${$self}{linebreaksAtEnd}{begin} *should be* 1 - if(${${${$arguments}{children}}[0]}{body} =~ m/^($blankLineToken)/){ - $logger->trace("Updating {linebreaksAtEnd}{begin} for ${$self}{name} as $blankLineToken or blank line found at beginning of argument child") if $is_t_switch_active; - ${$self}{linebreaksAtEnd}{begin} = 1 - } + if ( ${ ${ ${$arguments}{children} }[0] }{body} =~ m/^($blankLineToken)/ ) { + $logger->trace( + "Updating {linebreaksAtEnd}{begin} for ${$self}{name} as $blankLineToken or blank line found at beginning of argument child" + ) if $is_t_switch_active; + ${$self}{linebreaksAtEnd}{begin} = 1; + } # examine *first* child # situation: parent BodyStartsOnOwnLine == -1, but first child has BeginStartsOnOwnLine == 1 # problem: the *body* of parent actually starts after the arguments # solution: add a linebreak at the end of the begin statement of the parent so that # the child settings are obeyed. - # BodyStartsOnOwnLine == 0 will actually be controlled by the last arguments' + # BodyStartsOnOwnLine == 0 will actually be controlled by the last arguments' # settings of EndFinishesWithLineBreak - if( ${$self}{linebreaksAtEnd}{begin} == 0 - and ((defined ${$self}{BodyStartsOnOwnLine} and ${$self}{BodyStartsOnOwnLine}==-1) - or !(defined ${$self}{BodyStartsOnOwnLine})) - ){ - if(defined ${${${$arguments}{children}}[0]}{BeginStartsOnOwnLine} and ${${${$arguments}{children}}[0]}{BeginStartsOnOwnLine}>=1){ - my $BodyStringLogFile = ${$self}{aliases}{BodyStartsOnOwnLine}||"BodyStartsOnOwnLine"; - my $BeginStringLogFile = ${${${$arguments}{children}}[0]}{aliases}{BeginStartsOnOwnLine}||"BeginStartsOnOwnLine"; - my $BodyValue = (defined ${$self}{BodyStartsOnOwnLine}) ? ${$self}{BodyStartsOnOwnLine} : "0"; - $logger->trace("$BodyStringLogFile = $BodyValue (in ${$self}{name}), but first argument *should* begin on its own line (see $BeginStringLogFile)") if $is_t_switch_active; - - # possibly add a comment or a blank line, depending on if BeginStartsOnOwnLine == 2 or 3 respectively + if (${$self}{linebreaksAtEnd}{begin} == 0 + and ( ( defined ${$self}{BodyStartsOnOwnLine} and ${$self}{BodyStartsOnOwnLine} == -1 ) + or !( defined ${$self}{BodyStartsOnOwnLine} ) ) + ) + { + if ( defined ${ ${ ${$arguments}{children} }[0] }{BeginStartsOnOwnLine} + and ${ ${ ${$arguments}{children} }[0] }{BeginStartsOnOwnLine} >= 1 ) + { + my $BodyStringLogFile = ${$self}{aliases}{BodyStartsOnOwnLine} || "BodyStartsOnOwnLine"; + my $BeginStringLogFile + = ${ ${ ${$arguments}{children} }[0] }{aliases}{BeginStartsOnOwnLine} || "BeginStartsOnOwnLine"; + my $BodyValue = ( defined ${$self}{BodyStartsOnOwnLine} ) ? ${$self}{BodyStartsOnOwnLine} : "0"; + $logger->trace( + "$BodyStringLogFile = $BodyValue (in ${$self}{name}), but first argument *should* begin on its own line (see $BeginStringLogFile)" + ) if $is_t_switch_active; + + # possibly add a comment or a blank line, depending on if BeginStartsOnOwnLine == 2 or 3 respectively # at the end of the begin statement my $trailingCharacterToken = q(); - if(${${${$arguments}{children}}[0]}{BeginStartsOnOwnLine}==1){ - $logger->trace("Adding line breaks at the end of ${$self}{begin} (first argument, see $BeginStringLogFile == ${${${$arguments}{children}}[0]}{BeginStartsOnOwnLine})") if $is_t_switch_active; - } elsif(${${${$arguments}{children}}[0]}{BeginStartsOnOwnLine}==2){ - $logger->trace("Adding a % at the end of begin, ${$self}{begin} followed by a linebreak ($BeginStringLogFile == 2)") if $is_t_switch_active; - $trailingCharacterToken = "%".$self->add_comment_symbol; + if ( ${ ${ ${$arguments}{children} }[0] }{BeginStartsOnOwnLine} == 1 ) { + $logger->trace( + "Adding line breaks at the end of ${$self}{begin} (first argument, see $BeginStringLogFile == ${${${$arguments}{children}}[0]}{BeginStartsOnOwnLine})" + ) if $is_t_switch_active; + } + elsif ( ${ ${ ${$arguments}{children} }[0] }{BeginStartsOnOwnLine} == 2 ) { + $logger->trace( + "Adding a % at the end of begin, ${$self}{begin} followed by a linebreak ($BeginStringLogFile == 2)" + ) if $is_t_switch_active; + $trailingCharacterToken = "%" . $self->add_comment_symbol; $logger->trace("Removing trailing space on ${$self}{begin}") if $is_t_switch_active; ${$self}{begin} =~ s/\h*$//s; - } elsif (${${${$arguments}{children}}[0]}{BeginStartsOnOwnLine}==3) { - $logger->trace("Adding a blank line immediately ${$self}{begin} ($BeginStringLogFile==3)") if $is_t_switch_active; - $trailingCharacterToken = "\n".(${$mainSettings{modifyLineBreaks}}{preserveBlankLines}?$tokens{blanklines}:q()); + } + elsif ( ${ ${ ${$arguments}{children} }[0] }{BeginStartsOnOwnLine} == 3 ) { + $logger->trace("Adding a blank line immediately ${$self}{begin} ($BeginStringLogFile==3)") + if $is_t_switch_active; + $trailingCharacterToken = "\n" + . ( ${ $mainSettings{modifyLineBreaks} }{preserveBlankLines} ? $tokens{blanklines} : q() ); } # modification @@ -192,38 +232,47 @@ sub find_opt_mand_arguments{ ${$arguments}{replacementText} = ${$arguments}{id}; # children need to receive ancestor information, see test-cases/commands/commands-triple-nested.tex - foreach (@{${$arguments}{children}}){ - $logger->trace("Updating argument child of ${$self}{name} to include ${$self}{id} in ancestors") if $is_t_switch_active; - push(@{${$_}{ancestors}},{ancestorID=>${$self}{id},ancestorIndentation=>${$self}{indentation},type=>"natural"}); + foreach ( @{ ${$arguments}{children} } ) { + $logger->trace("Updating argument child of ${$self}{name} to include ${$self}{id} in ancestors") + if $is_t_switch_active; + push( + @{ ${$_}{ancestors} }, + { ancestorID => ${$self}{id}, ancestorIndentation => ${$self}{indentation}, type => "natural" } + ); } # the argument object only needs a trailing line break if the *last* child # did not add one at the end, and if BodyStartsOnOwnLine >= 1 - if( (defined ${${${$arguments}{children}}[-1]}{EndFinishesWithLineBreak} and ${${${$arguments}{children}}[-1]}{EndFinishesWithLineBreak}<1) - and (defined ${$self}{BodyStartsOnOwnLine} and ${$self}{BodyStartsOnOwnLine}>=1) ){ - $logger->trace("Updating replacementtext to include a linebreak for arguments in ${$self}{name}") if $is_t_switch_active; - ${$arguments}{replacementText} .= "\n" if(${$arguments}{linebreaksAtEnd}{end}); + if (( defined ${ ${ ${$arguments}{children} }[-1] }{EndFinishesWithLineBreak} + and ${ ${ ${$arguments}{children} }[-1] }{EndFinishesWithLineBreak} < 1 + ) + and ( defined ${$self}{BodyStartsOnOwnLine} and ${$self}{BodyStartsOnOwnLine} >= 1 ) + ) + { + $logger->trace("Updating replacementtext to include a linebreak for arguments in ${$self}{name}") + if $is_t_switch_active; + ${$arguments}{replacementText} .= "\n" if ( ${$arguments}{linebreaksAtEnd}{end} ); } # store children in special hash - push(@{${$self}{children}},$arguments); + push( @{ ${$self}{children} }, $arguments ); # remove the environment block, and replace with unique ID ${$self}{body} =~ s/${$arguments}{regexp}/${$arguments}{replacementText}/; # delete the regexp, as there's no need for it - delete ${${${$self}{children}}[-1]}{regexp}; + delete ${ ${ ${$self}{children} }[-1] }{regexp}; - $logger->trace(Dumper(\%{$arguments})) if($is_tt_switch_active); + $logger->trace( Dumper( \%{$arguments} ) ) if ($is_tt_switch_active); $logger->trace("replaced with ID: ${$arguments}{id}") if $is_tt_switch_active; - } else { + } + else { $logger->trace("... no arguments found") if $is_t_switch_active; } } - -sub create_unique_id{ +sub create_unique_id { my $self = shift; $ArgumentCounter++; @@ -231,45 +280,52 @@ sub create_unique_id{ return; } -sub get_arguments_regexp{ +sub get_arguments_regexp { - my $self = shift; + my $self = shift; my %input = @_; # blank line token my $blankLineToken = $tokens{blanklines}; # some calls to this routine need to account for the linebreaks at the end, some do not - my $lineBreaksAtEnd = (defined ${input}{mode} and ${input}{mode} eq 'lineBreaksAtEnd')?'\R*':q(); + my $lineBreaksAtEnd = ( defined ${input}{mode} and ${input}{mode} eq 'lineBreaksAtEnd' ) ? '\R*' : q(); # arguments Before, by default, includes beamer special and numbered arguments, for example #1 #2, etc - my $argumentsBefore = qr/${${$mainSettings{fineTuning}}{arguments}}{before}/; - my $argumentsBetween = qr/${${$mainSettings{fineTuning}}{arguments}}{between}/; + my $argumentsBefore = qr/${${$mainSettings{fineTuning}}{arguments}}{before}/; + my $argumentsBetween = qr/${${$mainSettings{fineTuning}}{arguments}}{between}/; - # commands are allowed strings between arguments, e.g node, decoration, etc, specified in stringsAllowedBetweenArguments +# commands are allowed strings between arguments, e.g node, decoration, etc, specified in stringsAllowedBetweenArguments my $stringsBetweenArguments = q(); - if(defined ${input}{stringBetweenArguments} and ${input}{stringBetweenArguments}==1 - and ref(${$mainSettings{commandCodeBlocks}}{stringsAllowedBetweenArguments}) eq "ARRAY"){ + if ( defined ${input}{stringBetweenArguments} + and ${input}{stringBetweenArguments} == 1 + and ref( ${ $mainSettings{commandCodeBlocks} }{stringsAllowedBetweenArguments} ) eq "ARRAY" ) + { # grab the strings allowed between arguments - my @stringsAllowedBetweenArguments = @{${$mainSettings{commandCodeBlocks}}{stringsAllowedBetweenArguments}}; + my @stringsAllowedBetweenArguments = @{ ${ $mainSettings{commandCodeBlocks} }{stringsAllowedBetweenArguments} }; - $logger->trace("*Looping through array for commandCodeBlocks->stringsAllowedBetweenArguments") if $is_t_switch_active ; + $logger->trace("*Looping through array for commandCodeBlocks->stringsAllowedBetweenArguments") + if $is_t_switch_active; # note that the zero'th element in this array contains the amalgamate switch, which we don't want! - foreach (@stringsAllowedBetweenArguments[1 .. $#stringsAllowedBetweenArguments]) { - $logger->trace("$_") if $is_t_switch_active ; - $stringsBetweenArguments .= ($stringsBetweenArguments eq ""?q():"|").$_; + foreach ( @stringsAllowedBetweenArguments[ 1 .. $#stringsAllowedBetweenArguments ] ) { + $logger->trace("$_") if $is_t_switch_active; + $stringsBetweenArguments .= ( $stringsBetweenArguments eq "" ? q() : "|" ) . $_; } $stringsBetweenArguments = qr/$stringsBetweenArguments/; + # report to log file - $logger->trace("*Strings allowed between arguments: $stringsBetweenArguments (see stringsAllowedBetweenArguments)") if $is_t_switch_active; - } + $logger->trace( + "*Strings allowed between arguments: $stringsBetweenArguments (see stringsAllowedBetweenArguments)") + if $is_t_switch_active; + } - if(defined ${input}{roundBrackets} and ${input}{roundBrackets}==1){ - # arguments regexp - return qr/ + if ( defined ${input}{roundBrackets} and ${input}{roundBrackets} == 1 ) { + + # arguments regexp + return qr/ ( # capture into $1 (?: (?:\h|\R|$blankLineToken|$trailingCommentRegExp|$argumentsBefore|$argumentsBetween|$stringsBetweenArguments)* @@ -346,8 +402,9 @@ sub get_arguments_regexp{ ($lineBreaksAtEnd) ) /sx; - } else { - return qr/ + } + else { + return qr/ ( # capture into $1 (?: (?:\h|\R|$blankLineToken|$trailingCommentRegExp|$argumentsBefore|$argumentsBetween|$stringsBetweenArguments)* @@ -395,24 +452,29 @@ sub get_arguments_regexp{ ($lineBreaksAtEnd) ) /sx; - } + } } -sub comma_else{ +sub comma_else { my $self = shift; # check for existence of \\ statement, and associated line break information $self->check_for_else_statement( - # else name regexp - elseNameRegExp=>qr/${${$mainSettings{fineTuning}}{modifyLineBreaks}}{comma}/, - # else statements name - ElseStartsOnOwnLine=>"CommaStartsOnOwnLine", - # end statements - ElseFinishesWithLineBreak=>"CommaFinishesWithLineBreak", - # for the YAML settings storage - storageNameAppend=>"comma", - # logfile information - logName=>"comma block, see CommaStartsOnOwnLine and CommaFinishesWithLineBreak", - ); + + # else name regexp + elseNameRegExp => qr/${${$mainSettings{fineTuning}}{modifyLineBreaks}}{comma}/, + + # else statements name + ElseStartsOnOwnLine => "CommaStartsOnOwnLine", + + # end statements + ElseFinishesWithLineBreak => "CommaFinishesWithLineBreak", + + # for the YAML settings storage + storageNameAppend => "comma", + + # logfile information + logName => "comma block, see CommaStartsOnOwnLine and CommaFinishesWithLineBreak", + ); } 1; diff --git a/Master/texmf-dist/scripts/latexindent/LatexIndent/BackUpFileProcedure.pm b/Master/texmf-dist/scripts/latexindent/LatexIndent/BackUpFileProcedure.pm index bcc2bb0fb3f..369f06d0754 100644 --- a/Master/texmf-dist/scripts/latexindent/LatexIndent/BackUpFileProcedure.pm +++ b/Master/texmf-dist/scripts/latexindent/LatexIndent/BackUpFileProcedure.pm @@ -1,4 +1,5 @@ package LatexIndent::BackUpFileProcedure; + # 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 @@ -19,17 +20,17 @@ use warnings; use LatexIndent::GetYamlSettings qw/%mainSettings/; use LatexIndent::Switches qw/%switches/; use LatexIndent::LogFile qw/$logger/; -use File::Basename; # to get the filename and directory path -use File::Copy; # to copy the original file to backup (if overwrite option set) +use File::Basename; # to get the filename and directory path +use File::Copy; # to copy the original file to backup (if overwrite option set) use Exporter qw/import/; our @EXPORT_OK = qw/create_back_up_file check_if_different/; # copy main file to a back up in the case of the overwrite switch being active -sub create_back_up_file{ +sub create_back_up_file { my $self = shift; - return unless(${$self}{overwrite}); + return unless ( ${$self}{overwrite} ); # if we want to over write the current file create a backup first $logger->info("*Backup procedure (-w flag active):"); @@ -37,121 +38,128 @@ sub create_back_up_file{ my $fileName = ${$self}{fileName}; # grab the file extension preferences - my %fileExtensionPreference= %{$mainSettings{fileExtensionPreference}}; + my %fileExtensionPreference = %{ $mainSettings{fileExtensionPreference} }; - # sort the file extensions by preference - my @fileExtensions = sort { $fileExtensionPreference{$a} <=> $fileExtensionPreference{$b} } keys(%fileExtensionPreference); + # sort the file extensions by preference + my @fileExtensions + = sort { $fileExtensionPreference{$a} <=> $fileExtensionPreference{$b} } keys(%fileExtensionPreference); # backup file name is the base name - my $backupFile = basename(${$self}{fileName},@fileExtensions); - + my $backupFile = basename( ${$self}{fileName}, @fileExtensions ); + # add the user's backup directory to the backup path $backupFile = "${$self}{cruftDirectory}/$backupFile"; # local variables, determined from the YAML settings - my $onlyOneBackUp = $mainSettings{onlyOneBackUp}; - my $maxNumberOfBackUps = $mainSettings{maxNumberOfBackUps}; - my $cycleThroughBackUps= $mainSettings{cycleThroughBackUps}; - my $backupExtension= $mainSettings{backupExtension}; - + my $onlyOneBackUp = $mainSettings{onlyOneBackUp}; + my $maxNumberOfBackUps = $mainSettings{maxNumberOfBackUps}; + my $cycleThroughBackUps = $mainSettings{cycleThroughBackUps}; + my $backupExtension = $mainSettings{backupExtension}; + # if both ($onlyOneBackUp and $maxNumberOfBackUps) then we have # a conflict- er on the side of caution and turn off onlyOneBackUp - if($onlyOneBackUp and $maxNumberOfBackUps>1) { + if ( $onlyOneBackUp and $maxNumberOfBackUps > 1 ) { $logger->warn("*onlyOneBackUp=$onlyOneBackUp and maxNumberOfBackUps: $maxNumberOfBackUps"); $logger->warn("setting onlyOneBackUp=0 which will allow you to reach $maxNumberOfBackUps back ups"); $onlyOneBackUp = 0; } - + # if the user has specified that $maxNumberOfBackUps = 1 then # they only want one backup - if($maxNumberOfBackUps==1) { - $onlyOneBackUp=1 ; + if ( $maxNumberOfBackUps == 1 ) { + $onlyOneBackUp = 1; $logger->info("you set maxNumberOfBackUps=1, so I'm setting onlyOneBackUp: 1 "); - } elsif($maxNumberOfBackUps<=0 and !$onlyOneBackUp) { - $onlyOneBackUp=0 ; - $maxNumberOfBackUps=-1; } - + elsif ( $maxNumberOfBackUps <= 0 and !$onlyOneBackUp ) { + $onlyOneBackUp = 0; + $maxNumberOfBackUps = -1; + } + # if onlyOneBackUp is set, then the backup file will # be overwritten each time - if($onlyOneBackUp) { + if ($onlyOneBackUp) { $backupFile .= $backupExtension; $logger->info("copying $fileName to $backupFile"); - $logger->info("$backupFile was overwritten (see onlyOneBackUp)") if (-e $backupFile); - } else { + $logger->info("$backupFile was overwritten (see onlyOneBackUp)") if ( -e $backupFile ); + } + else { # start with a backup file .bak0 (or whatever $backupExtension is present) my $backupCounter = 0; - $backupFile .= $backupExtension.$backupCounter; - + $backupFile .= $backupExtension . $backupCounter; + # if it exists, then keep going: .bak0, .bak1, ... - while (-e $backupFile or $maxNumberOfBackUps>1) { - if($backupCounter==$maxNumberOfBackUps) { + while ( -e $backupFile or $maxNumberOfBackUps > 1 ) { + if ( $backupCounter == $maxNumberOfBackUps ) { $logger->info("maxNumberOfBackUps reached ($maxNumberOfBackUps, see maxNumberOfBackUps)"); - + # some users may wish to cycle through back up files, e.g: # copy myfile.bak1 to myfile.bak0 # copy myfile.bak2 to myfile.bak1 # copy myfile.bak3 to myfile.bak2 # # current back up is stored in myfile.bak4 - if($cycleThroughBackUps) { + if ($cycleThroughBackUps) { $logger->info("cycleThroughBackUps detected (see cycleThroughBackUps) "); - for(my $i=1;$i<=$maxNumberOfBackUps;$i++) { + for ( my $i = 1; $i <= $maxNumberOfBackUps; $i++ ) { + # remove number from backUpFile my $oldBackupFile = $backupFile; $oldBackupFile =~ s/$backupExtension.*/$backupExtension/; my $newBackupFile = $oldBackupFile; - + # add numbers back on $oldBackupFile .= $i; - $newBackupFile .= $i-1; - + $newBackupFile .= $i - 1; + # check that the oldBackupFile exists - if(-e $oldBackupFile){ - $logger->info(" copying $oldBackupFile to $newBackupFile "); + if ( -e $oldBackupFile ) { + $logger->info(" copying $oldBackupFile to $newBackupFile "); my $backUpFilePossible = 1; - copy($oldBackupFile,$newBackupFile) or ($backUpFilePossible = 0); - if ($backUpFilePossible==0){ - $logger->fatal("*Could not write to backup file $backupFile. Please check permissions. Exiting."); - $logger->fatal("Exiting, no indendation done."); + copy( $oldBackupFile, $newBackupFile ) or ( $backUpFilePossible = 0 ); + if ( $backUpFilePossible == 0 ) { + $logger->fatal( + "*Could not write to backup file $backupFile. Please check permissions. Exiting."); + $logger->fatal("Exiting, no indendation done."); $self->output_logfile(); exit(5); } } } } - + # rest maxNumberOfBackUps - $maxNumberOfBackUps=1 ; - last; # break out of the loop - } elsif(!(-e $backupFile)) { - $maxNumberOfBackUps=1; - last; # break out of the loop + $maxNumberOfBackUps = 1; + last; # break out of the loop + } + elsif ( !( -e $backupFile ) ) { + $maxNumberOfBackUps = 1; + last; # break out of the loop } - $logger->info("$backupFile already exists, incrementing by 1... (see maxNumberOfBackUps and onlyOneBackUp)"); + $logger->info( + "$backupFile already exists, incrementing by 1... (see maxNumberOfBackUps and onlyOneBackUp)"); $backupCounter++; $backupFile =~ s/$backupExtension.*/$backupExtension$backupCounter/; } $logger->info("copying $fileName to $backupFile"); } - + # output these lines to the log file $logger->info("Backup file: $backupFile"); $logger->info("$fileName will be overwritten after indentation"); my $backUpFilePossible = 1; - copy($fileName,$backupFile) or ($backUpFilePossible = 0); - if ($backUpFilePossible==0){ + copy( $fileName, $backupFile ) or ( $backUpFilePossible = 0 ); + if ( $backUpFilePossible == 0 ) { $logger->fatal("*Could not write to backup file $backupFile. Please check permissions."); - $logger->fatal("Exiting, no indendation done."); + $logger->fatal("Exiting, no indendation done."); $self->output_logfile(); exit(5); } } -sub check_if_different{ +sub check_if_different { my $self = shift; - if (${$self}{originalBody} eq ${$self}{body}){ + if ( ${$self}{originalBody} eq ${$self}{body} ) { $logger->info("*-wd switch active"); $logger->info("Original body matches indented body, NOT overwriting, no back up files created"); return; @@ -161,7 +169,7 @@ sub check_if_different{ $logger->info("*-wd switch active"); $logger->info("Original body is *different* from indented body"); $logger->info("activating overwrite switch, -w"); - ${$self}{overwrite}=1; + ${$self}{overwrite} = 1; $self->create_back_up_file; } 1; diff --git a/Master/texmf-dist/scripts/latexindent/LatexIndent/BlankLines.pm b/Master/texmf-dist/scripts/latexindent/LatexIndent/BlankLines.pm index b1a3cee40dd..d0fee3cbe6a 100644 --- a/Master/texmf-dist/scripts/latexindent/LatexIndent/BlankLines.pm +++ b/Master/texmf-dist/scripts/latexindent/LatexIndent/BlankLines.pm @@ -1,4 +1,5 @@ package LatexIndent::BlankLines; + # 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 @@ -23,12 +24,12 @@ use LatexIndent::LogFile qw/$logger/; use Exporter qw/import/; our @EXPORT_OK = qw/protect_blank_lines unprotect_blank_lines condense_blank_lines/; -sub protect_blank_lines{ +sub protect_blank_lines { my $self = shift; - - unless(${$mainSettings{modifyLineBreaks}}{preserveBlankLines}){ + + unless ( ${ $mainSettings{modifyLineBreaks} }{preserveBlankLines} ) { $logger->trace("*Blank lines will not be protected (preserveBlankLines=0)") if $is_t_switch_active; - return + return; } $logger->trace("*Protecting blank lines (see preserveBlankLines)") if $is_t_switch_active; @@ -36,48 +37,54 @@ sub protect_blank_lines{ return; } -sub condense_blank_lines{ +sub condense_blank_lines { my $self = shift; - + $logger->trace("*condense blank lines routine") if $is_t_switch_active; + # if preserveBlankLines is set to 0, then the blank-line-token will not be present # in the document -- we change that here - if(${$mainSettings{modifyLineBreaks}}{preserveBlankLines}==0){ + if ( ${ $mainSettings{modifyLineBreaks} }{preserveBlankLines} == 0 ) { + # turn the switch on - ${$mainSettings{modifyLineBreaks}}{preserveBlankLines}=1; + ${ $mainSettings{modifyLineBreaks} }{preserveBlankLines} = 1; # log file information - $logger->trace("Updating body to include blank line token, this requires preserveBlankLines = 1") if($is_tt_switch_active); - $logger->trace("(any blanklines that could have been removed, would have done so by this point)") if($is_tt_switch_active); + $logger->trace("Updating body to include blank line token, this requires preserveBlankLines = 1") + if ($is_tt_switch_active); + $logger->trace("(any blanklines that could have been removed, would have done so by this point)") + if ($is_tt_switch_active); # make the call - $self->protect_blank_lines ; - $logger->trace("body now looks like:\n${$self}{body}") if($is_tt_switch_active); - } + $self->protect_blank_lines; + $logger->trace("body now looks like:\n${$self}{body}") if ($is_tt_switch_active); + } # grab the value from the settings - my $condenseMultipleBlankLinesInto = ${$mainSettings{modifyLineBreaks}}{condenseMultipleBlankLinesInto}; + my $condenseMultipleBlankLinesInto = ${ $mainSettings{modifyLineBreaks} }{condenseMultipleBlankLinesInto}; # grab the blank-line-token my $blankLineToken = $tokens{blanklines}; # condense! - $logger->trace("Condensing multiple blank lines into $condenseMultipleBlankLinesInto (see condenseMultipleBlankLinesInto)") if $is_t_switch_active; + $logger->trace( + "Condensing multiple blank lines into $condenseMultipleBlankLinesInto (see condenseMultipleBlankLinesInto)") + if $is_t_switch_active; my $replacementToken = $blankLineToken; - for (my $i=1; $i<$condenseMultipleBlankLinesInto; $i++ ){ + for ( my $i = 1; $i < $condenseMultipleBlankLinesInto; $i++ ) { $replacementToken .= "\n$blankLineToken"; } - $logger->trace("blank line replacement token: $replacementToken") if($is_tt_switch_active); + $logger->trace("blank line replacement token: $replacementToken") if ($is_tt_switch_active); ${$self}{body} =~ s/($blankLineToken\h*\R*\h*){1,}$blankLineToken/$replacementToken/mgs; - $logger->trace("body now looks like:\n${$self}{body}") if($is_tt_switch_active); + $logger->trace("body now looks like:\n${$self}{body}") if ($is_tt_switch_active); return; } -sub unprotect_blank_lines{ +sub unprotect_blank_lines { my $self = shift; - + # remove any empty lines that might have been added by the text_wrap routine; see, for example, # test-cases/maxLineChars/multi-object-all.tex -l=multi-object2.yaml -m ${$self}{body} =~ s/^\h*\R//mg; @@ -85,12 +92,13 @@ sub unprotect_blank_lines{ $logger->trace("Unprotecting blank lines (see preserveBlankLines)") if $is_t_switch_active; my $blankLineToken = $tokens{blanklines}; - if($is_m_switch_active and ${$mainSettings{modifyLineBreaks}{textWrapOptions}}{huge} ne "overflow"){ - $blankLineToken = join("(?:\\h|\\R)*",split(//,$tokens{blanklines})); + if ( $is_m_switch_active and ${ $mainSettings{modifyLineBreaks}{textWrapOptions} }{huge} ne "overflow" ) { + $blankLineToken = join( "(?:\\h|\\R)*", split( //, $tokens{blanklines} ) ); } # loop through the body, looking for the blank line token - while(${$self}{body} =~ m/$blankLineToken/s){ + while ( ${$self}{body} =~ m/$blankLineToken/s ) { + # when the blank line token occupies the whole line ${$self}{body} =~ s/^\h*$blankLineToken$//mg; @@ -104,8 +112,8 @@ sub unprotect_blank_lines{ ${$self}{body} =~ s/^$blankLineToken\h*(.*?)$/$1."\n"/emg; } $logger->trace("Finished unprotecting lines (see preserveBlankLines)") if $is_t_switch_active; - $logger->trace("body now looks like:") if($is_tt_switch_active); - $logger->trace("${$self}{body}") if($is_tt_switch_active); + $logger->trace("body now looks like:") if ($is_tt_switch_active); + $logger->trace("${$self}{body}") if ($is_tt_switch_active); } 1; diff --git a/Master/texmf-dist/scripts/latexindent/LatexIndent/Braces.pm b/Master/texmf-dist/scripts/latexindent/LatexIndent/Braces.pm index 4861dd1f6a6..80efc02e523 100644 --- a/Master/texmf-dist/scripts/latexindent/LatexIndent/Braces.pm +++ b/Master/texmf-dist/scripts/latexindent/LatexIndent/Braces.pm @@ -1,4 +1,5 @@ package LatexIndent::Braces; + # 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 @@ -18,37 +19,37 @@ use strict; use warnings; use LatexIndent::TrailingComments qw/$trailingCommentRegExp/; use LatexIndent::Command qw/$commandRegExp $commandRegExpTrailingComment $optAndMandAndRoundBracketsRegExpLineBreaks/; -use LatexIndent::KeyEqualsValuesBraces qw/$key_equals_values_bracesRegExp $key_equals_values_bracesRegExpTrailingComment/; +use LatexIndent::KeyEqualsValuesBraces + qw/$key_equals_values_bracesRegExp $key_equals_values_bracesRegExpTrailingComment/; use LatexIndent::NamedGroupingBracesBrackets qw/$grouping_braces_regexp $grouping_braces_regexpTrailingComment/; -use LatexIndent::UnNamedGroupingBracesBrackets qw/$un_named_grouping_braces_RegExp $un_named_grouping_braces_RegExp_trailing_comment/; +use LatexIndent::UnNamedGroupingBracesBrackets + qw/$un_named_grouping_braces_RegExp $un_named_grouping_braces_RegExp_trailing_comment/; use LatexIndent::Switches qw/$is_t_switch_active $is_tt_switch_active/; use LatexIndent::LogFile qw/$logger/; use Data::Dumper; use Exporter qw/import/; -our @ISA = "LatexIndent::Document"; # class inheritance, Programming Perl, pg 321 +our @ISA = "LatexIndent::Document"; # class inheritance, Programming Perl, pg 321 our @EXPORT_OK = qw/find_commands_or_key_equals_values_braces $braceBracketRegExpBasic/; our $commandCounter; our $braceBracketRegExpBasic = qr/\{|\[/; -sub find_commands_or_key_equals_values_braces{ +sub find_commands_or_key_equals_values_braces { my $self = shift; - $logger->trace("*Searching for commands with optional and/or mandatory arguments AND key = {value}") if $is_t_switch_active ; + $logger->trace("*Searching for commands with optional and/or mandatory arguments AND key = {value}") + if $is_t_switch_active; # match either a \\command or key={value} - while( ${$self}{body} =~ m/$commandRegExpTrailingComment/ - or - ${$self}{body} =~ m/$key_equals_values_bracesRegExpTrailingComment/ - or - ${$self}{body} =~ m/$grouping_braces_regexpTrailingComment/ - or - ${$self}{body} =~ m/$un_named_grouping_braces_RegExp_trailing_comment/ - ){ - if(${$self}{body} =~ m/$commandRegExpTrailingComment/){ - - # global substitution - ${$self}{body} =~ s/ + while (${$self}{body} =~ m/$commandRegExpTrailingComment/ + or ${$self}{body} =~ m/$key_equals_values_bracesRegExpTrailingComment/ + or ${$self}{body} =~ m/$grouping_braces_regexpTrailingComment/ + or ${$self}{body} =~ m/$un_named_grouping_braces_RegExp_trailing_comment/ ) + { + if ( ${$self}{body} =~ m/$commandRegExpTrailingComment/ ) { + + # global substitution + ${$self}{body} =~ s/ $commandRegExpTrailingComment / # create a new command object @@ -79,10 +80,11 @@ sub find_commands_or_key_equals_values_braces{ ${@{${$self}{children}}[-1]}{replacementText}.($8?($10?$10:q()):q()); /xseg; - } elsif (${$self}{body} =~ m/$key_equals_values_bracesRegExpTrailingComment/){ + } + elsif ( ${$self}{body} =~ m/$key_equals_values_bracesRegExpTrailingComment/ ) { - # global substitution - ${$self}{body} =~ s/ + # global substitution + ${$self}{body} =~ s/ $key_equals_values_bracesRegExpTrailingComment / # create a new key_equals_values_braces object @@ -114,11 +116,12 @@ sub find_commands_or_key_equals_values_braces{ $self->get_settings_and_store_new_object($key_equals_values_braces); ${@{${$self}{children}}[-1]}{replacementText}.($9?($11?$11:q()):q()); /xseg; - - } elsif (${$self}{body} =~ m/$grouping_braces_regexpTrailingComment/){ - # global substitution - ${$self}{body} =~ s/ + } + elsif ( ${$self}{body} =~ m/$grouping_braces_regexpTrailingComment/ ) { + + # global substitution + ${$self}{body} =~ s/ $grouping_braces_regexpTrailingComment / # create a new key_equals_values_braces object @@ -149,9 +152,11 @@ sub find_commands_or_key_equals_values_braces{ ${@{${$self}{children}}[-1]}{replacementText}.($8?($9?$9:q()):q()); /xseg; - } elsif (${$self}{body} =~ m/$un_named_grouping_braces_RegExp_trailing_comment/) { - # global substitution - ${$self}{body} =~ s/ + } + elsif ( ${$self}{body} =~ m/$un_named_grouping_braces_RegExp_trailing_comment/ ) { + + # global substitution + ${$self}{body} =~ s/ $un_named_grouping_braces_RegExp_trailing_comment / # create a new Un-named-grouping-braces-brackets object @@ -181,8 +186,8 @@ sub find_commands_or_key_equals_values_braces{ ${@{${$self}{children}}[-1]}{replacementText}.($6?($8?$8:q()):q()); /xseg; + } } - } return; } diff --git a/Master/texmf-dist/scripts/latexindent/LatexIndent/Check.pm b/Master/texmf-dist/scripts/latexindent/LatexIndent/Check.pm index 67efab2348b..76d75cc9892 100644 --- a/Master/texmf-dist/scripts/latexindent/LatexIndent/Check.pm +++ b/Master/texmf-dist/scripts/latexindent/LatexIndent/Check.pm @@ -1,4 +1,5 @@ package LatexIndent::Check; + # 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 @@ -19,7 +20,7 @@ use warnings; use Exporter qw/import/; use LatexIndent::LogFile qw/$logger/; use LatexIndent::Switches qw/$is_m_switch_active $is_check_verbose_switch_active/; -our @ISA = "LatexIndent::Document"; # class inheritance, Programming Perl, pg 321 +our @ISA = "LatexIndent::Document"; # class inheritance, Programming Perl, pg 321 our @EXPORT_OK = qw/simple_diff/; sub simple_diff { @@ -29,21 +30,22 @@ sub simple_diff { $logger->info("*simple diff: (check switch active)"); # check switch work below here - if (${$self}{originalBody} eq ${$self}{body}){ + if ( ${$self}{originalBody} eq ${$self}{body} ) { $logger->info("no differences, no diff to report"); return; } # otherwise we loop through the old and new body, and make comparisons - my @oldBody = split("\n",${$self}{originalBody}); - my @newBody = split("\n",${$self}{body}); - my @diff = (); + my @oldBody = split( "\n", ${$self}{originalBody} ); + my @newBody = split( "\n", ${$self}{body} ); + my @diff = (); # this loop stores the differences ... - if($is_m_switch_active){ + if ($is_m_switch_active) { + # if -m *is* active, then the number of lines in old and new may not be the same # so we need to go through the options - my $maxLines = ($#oldBody >= $#newBody ? $#oldBody : $#newBody); + my $maxLines = ( $#oldBody >= $#newBody ? $#oldBody : $#newBody ); # loop through to maxLines, accounting for the three scenarios: # @@ -51,78 +53,89 @@ sub simple_diff { # oldBody[lineCount] defined and newBody[lineCount] not defined # oldBody[lineCount] not defined and newBody[lineCount] defined # - for (my $lineCount=0;$lineCount<=$maxLines;$lineCount++){ - if ($lineCount<=$#oldBody and $lineCount<=$#newBody ){ - if ($oldBody[$lineCount] ne $newBody[$lineCount]){ - push(@diff,{old=>$oldBody[$lineCount],new=>$newBody[$lineCount],lineNumber=>$lineCount+1}); - } - } elsif ($lineCount<=$#oldBody) { - push(@diff,{old=>$oldBody[$lineCount],lineNumber=>$lineCount+1}); - } else { - push(@diff,{new=>$newBody[$lineCount],lineNumber=>$lineCount+1}); - } + for ( my $lineCount = 0; $lineCount <= $maxLines; $lineCount++ ) { + if ( $lineCount <= $#oldBody and $lineCount <= $#newBody ) { + if ( $oldBody[$lineCount] ne $newBody[$lineCount] ) { + push( @diff, + { old => $oldBody[$lineCount], new => $newBody[$lineCount], lineNumber => $lineCount + 1 } ); + } + } + elsif ( $lineCount <= $#oldBody ) { + push( @diff, { old => $oldBody[$lineCount], lineNumber => $lineCount + 1 } ); + } + else { + push( @diff, { new => $newBody[$lineCount], lineNumber => $lineCount + 1 } ); + } } - } else { + } + else { # if -m is not active, then the number of lines in old and new will be the same - for (my $lineCount=0;$lineCount<=$#oldBody;$lineCount++){ - if ($oldBody[$lineCount] ne $newBody[$lineCount]){ - push(@diff,{old=>$oldBody[$lineCount],new=>$newBody[$lineCount],lineNumber=>$lineCount+1}); - } + for ( my $lineCount = 0; $lineCount <= $#oldBody; $lineCount++ ) { + if ( $oldBody[$lineCount] ne $newBody[$lineCount] ) { + push( @diff, + { old => $oldBody[$lineCount], new => $newBody[$lineCount], lineNumber => $lineCount + 1 } ); + } } } # initialise the old and new tmp body for storage - my $tmpOldBody = '-'; - my $tmpNewBody = '+'; + my $tmpOldBody = '-'; + my $tmpNewBody = '+'; my $previousLineNumber = -1; # and the 'diff chunk' storage array - my @diffChunks = (); - my $diffChunkFirstLineNumber = ${$diff[0]}{lineNumber}; + my @diffChunks = (); + my $diffChunkFirstLineNumber = ${ $diff[0] }{lineNumber}; # ... and this loop combines the diffs into chunks - for my $i (0..$#diff) { + for my $i ( 0 .. $#diff ) { - my $currentLineNumber = ${$diff[$i]}{lineNumber}; + my $currentLineNumber = ${ $diff[$i] }{lineNumber}; - if ($i == $#diff - or ( $previousLineNumber>=0 and $currentLineNumber>($previousLineNumber+1) )){ + if ( $i == $#diff + or ( $previousLineNumber >= 0 and $currentLineNumber > ( $previousLineNumber + 1 ) ) ) + { - my $lastLine = ${$diff[$i-1]}{lineNumber}; + my $lastLine = ${ $diff[ $i - 1 ] }{lineNumber}; - if ($i == $#diff){ + if ( $i == $#diff ) { $lastLine = $currentLineNumber; - $tmpOldBody .= ($tmpOldBody eq '-' ? q() : "\n-").${$diff[$i]}{old}; - $tmpNewBody .= ($tmpNewBody eq '+' ? q() : "\n+").${$diff[$i]}{new}; + $tmpOldBody .= ( $tmpOldBody eq '-' ? q() : "\n-" ) . ${ $diff[$i] }{old}; + $tmpNewBody .= ( $tmpNewBody eq '+' ? q() : "\n+" ) . ${ $diff[$i] }{new}; } - push(@diffChunks, {old=>$tmpOldBody, - new=>$tmpNewBody, - firstLine=>$diffChunkFirstLineNumber, - lastLine=>$lastLine } ); - - $tmpOldBody = '-'.${$diff[$i]}{old} if defined ${$diff[$i]}{old}; - $tmpNewBody = '+'.${$diff[$i]}{new} if defined ${$diff[$i]}{new}; - $diffChunkFirstLineNumber = $currentLineNumber; - } else { - $tmpOldBody .= ($tmpOldBody eq '-' ? q() : "\n-").${$diff[$i]}{old} if defined ${$diff[$i]}{old}; - $tmpNewBody .= ($tmpNewBody eq '+' ? q() : "\n+").${$diff[$i]}{new} if defined ${$diff[$i]}{new}; + push( + @diffChunks, + { old => $tmpOldBody, + new => $tmpNewBody, + firstLine => $diffChunkFirstLineNumber, + lastLine => $lastLine + } + ); + + $tmpOldBody = '-' . ${ $diff[$i] }{old} if defined ${ $diff[$i] }{old}; + $tmpNewBody = '+' . ${ $diff[$i] }{new} if defined ${ $diff[$i] }{new}; + $diffChunkFirstLineNumber = $currentLineNumber; + } + else { + $tmpOldBody .= ( $tmpOldBody eq '-' ? q() : "\n-" ) . ${ $diff[$i] }{old} if defined ${ $diff[$i] }{old}; + $tmpNewBody .= ( $tmpNewBody eq '+' ? q() : "\n+" ) . ${ $diff[$i] }{new} if defined ${ $diff[$i] }{new}; } - $previousLineNumber = ${$diff[$i]}{lineNumber}; + $previousLineNumber = ${ $diff[$i] }{lineNumber}; } # finally, output the diff chunks - foreach (@diffChunks){ + foreach (@diffChunks) { $logger->info("@@ ${$_}{firstLine} -- ${$_}{lastLine} @@"); - $logger->info(${$_}{old}); - $logger->info(${$_}{new}); + $logger->info( ${$_}{old} ); + $logger->info( ${$_}{new} ); # possibly output to terminal - if($is_check_verbose_switch_active){ + if ($is_check_verbose_switch_active) { print "\n@@ ${$_}{firstLine} -- ${$_}{lastLine} @@\n"; - print ${$_}{old},"\n"; - print ${$_}{new},"\n"; + print ${$_}{old}, "\n"; + print ${$_}{new}, "\n"; } } } diff --git a/Master/texmf-dist/scripts/latexindent/LatexIndent/Command.pm b/Master/texmf-dist/scripts/latexindent/LatexIndent/Command.pm index b35577ab96c..e919f33d11e 100755 --- a/Master/texmf-dist/scripts/latexindent/LatexIndent/Command.pm +++ b/Master/texmf-dist/scripts/latexindent/LatexIndent/Command.pm @@ -1,4 +1,5 @@ package LatexIndent::Command; + # 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 @@ -23,38 +24,42 @@ use LatexIndent::GetYamlSettings qw/%mainSettings/; use LatexIndent::LogFile qw/$logger/; use Data::Dumper; use Exporter qw/import/; -our @ISA = "LatexIndent::Document"; # class inheritance, Programming Perl, pg 321 -our @EXPORT_OK = qw/construct_command_regexp $commandRegExp $commandRegExpTrailingComment $optAndMandAndRoundBracketsRegExpLineBreaks/; +our @ISA = "LatexIndent::Document"; # class inheritance, Programming Perl, pg 321 +our @EXPORT_OK + = qw/construct_command_regexp $commandRegExp $commandRegExpTrailingComment $optAndMandAndRoundBracketsRegExpLineBreaks/; our $commandCounter; our $commandRegExp; -our $commandRegExpTrailingComment; -our $optAndMandAndRoundBracketsRegExp; -our $optAndMandAndRoundBracketsRegExpLineBreaks; +our $commandRegExpTrailingComment; +our $optAndMandAndRoundBracketsRegExp; +our $optAndMandAndRoundBracketsRegExpLineBreaks; -# store the regular expresssion for matching and replacing -sub construct_command_regexp{ +# store the regular expresssion for matching and replacing +sub construct_command_regexp { my $self = shift; $optAndMandAndRoundBracketsRegExp = $self->get_arguments_regexp( - roundBrackets=>${$mainSettings{commandCodeBlocks}}{roundParenthesesAllowed}, - stringBetweenArguments=>1); + roundBrackets => ${ $mainSettings{commandCodeBlocks} }{roundParenthesesAllowed}, + stringBetweenArguments => 1 + ); $optAndMandAndRoundBracketsRegExpLineBreaks = $self->get_arguments_regexp( - roundBrackets=>${$mainSettings{commandCodeBlocks}}{roundParenthesesAllowed}, - mode=>"lineBreaksAtEnd", - stringBetweenArguments=>1); + roundBrackets => ${ $mainSettings{commandCodeBlocks} }{roundParenthesesAllowed}, + mode => "lineBreaksAtEnd", + stringBetweenArguments => 1 + ); # put together a list of the special command names (this was mostly motivated by the \@ifnextchar[ issue) my $commandNameSpecialRegExp = q(); - if(ref(${$mainSettings{commandCodeBlocks}}{commandNameSpecial}) eq "ARRAY"){ + if ( ref( ${ $mainSettings{commandCodeBlocks} }{commandNameSpecial} ) eq "ARRAY" ) { - my @commandNameSpecial = @{${$mainSettings{commandCodeBlocks}}{commandNameSpecial}}; - $logger->trace("*Looping through array for commandCodeBlocks->commandNameSpecial") if $is_t_switch_active ; + my @commandNameSpecial = @{ ${ $mainSettings{commandCodeBlocks} }{commandNameSpecial} }; + $logger->trace("*Looping through array for commandCodeBlocks->commandNameSpecial") + if $is_t_switch_active; # note that the zero'th element in this array contains the amalgamate switch, which we don't want! - foreach (@commandNameSpecial[1 .. $#commandNameSpecial]) { - $logger->trace("$_") if $is_t_switch_active ; - $commandNameSpecialRegExp .= ($commandNameSpecialRegExp eq ""?q():"|").$_; + foreach ( @commandNameSpecial[ 1 .. $#commandNameSpecial ] ) { + $logger->trace("$_") if $is_t_switch_active; + $commandNameSpecialRegExp .= ( $commandNameSpecialRegExp eq "" ? q() : "|" ) . $_; } # turn the above into a regexp @@ -62,10 +67,11 @@ sub construct_command_regexp{ } # details to log file - $logger->trace("*The special command names regexp is: $commandNameSpecialRegExp (see commandNameSpecial)") if $is_t_switch_active; + $logger->trace("*The special command names regexp is: $commandNameSpecialRegExp (see commandNameSpecial)") + if $is_t_switch_active; # read from fine tuning - my $commandNameRegExp = qr/${${$mainSettings{fineTuning}}{commands}}{name}/; + my $commandNameRegExp = qr/${${$mainSettings{fineTuning}}{commands}}{name}/; # construct the command regexp $commandRegExp = qr/ @@ -84,7 +90,7 @@ sub construct_command_regexp{ } -sub tasks_particular_to_each_object{ +sub tasks_particular_to_each_object { my $self = shift; # check for adding/removing linebreaks before = @@ -94,88 +100,114 @@ sub tasks_particular_to_each_object{ $self->find_opt_mand_arguments; # situation: ${${$self}{linebreaksAtEnd}}{end} == 1, and the argument container object - # still contains a linebreak at the end; in this case, we need to remove the linebreak from + # still contains a linebreak at the end; in this case, we need to remove the linebreak from # the container object - if(${${$self}{linebreaksAtEnd}}{end} == 1 - and ${${${$self}{children}}[0]}{body} =~ m/\R$/s - and !${$self}{endImmediatelyFollowedByComment}){ - $logger->trace("Removing linebreak from argument container of ${$self}{name}") if $is_t_switch_active; - ${${${$self}{children}}[0]}{body} =~ s/\R$//s; - ${${${${$self}{children}}[0]}{linebreaksAtEnd}}{body} = 0; + if ( ${ ${$self}{linebreaksAtEnd} }{end} == 1 + and ${ ${ ${$self}{children} }[0] }{body} =~ m/\R$/s + and !${$self}{endImmediatelyFollowedByComment} ) + { + $logger->trace("Removing linebreak from argument container of ${$self}{name}") + if $is_t_switch_active; + ${ ${ ${$self}{children} }[0] }{body} =~ s/\R$//s; + ${ ${ ${ ${$self}{children} }[0] }{linebreaksAtEnd} }{body} = 0; } # situation: ${${$self}{linebreaksAtEnd}}{end} == 1 and the last argument specifies # EndFinishesWithLineBreaks = 0 (see test-cases/commands/just-one-command-mod10.tex) - if(${${$self}{linebreaksAtEnd}}{end} == 1 - and defined ${${${${$self}{children}}[0]}{children}[-1]}{EndFinishesWithLineBreak} - and ${${${${$self}{children}}[0]}{children}[-1]}{EndFinishesWithLineBreak} == -1 - ){ - $logger->trace("Switching linebreaksAtEnd{end} to be 0 in command ${$self}{name} as last argument specifies EndFinishesWithLineBreak == 0") if $is_t_switch_active; - ${${$self}{linebreaksAtEnd}}{end} = 0; - ${$self}{EndFinishesWithLineBreak} = -1; - } - - # if the last argument finishes with a linebreak, it won't get interpreted at + if ( ${ ${$self}{linebreaksAtEnd} }{end} == 1 + and defined ${ ${ ${ ${$self}{children} }[0] }{children}[-1] }{EndFinishesWithLineBreak} + and ${ ${ ${ ${$self}{children} }[0] }{children}[-1] }{EndFinishesWithLineBreak} == -1 ) + { + $logger->trace( + "Switching linebreaksAtEnd{end} to be 0 in command ${$self}{name} as last argument specifies EndFinishesWithLineBreak == 0" + ) if $is_t_switch_active; + ${ ${$self}{linebreaksAtEnd} }{end} = 0; + ${$self}{EndFinishesWithLineBreak} = -1; + } + + # if the last argument finishes with a linebreak, it won't get interpreted at # the right time (see test-cases/commands/commands-one-line-nested-simple-mod1.tex for example) # so this little bit fixes it - if(${${${${${$self}{children}}[0]}{children}[-1]}{linebreaksAtEnd}}{end} and ${${$self}{linebreaksAtEnd}}{end} == 0 - and defined ${${${${$self}{children}}[0]}{children}[-1]}{EndFinishesWithLineBreak} - and ${${${${$self}{children}}[0]}{children}[-1]}{EndFinishesWithLineBreak} >= 1 - and !${$self}{endImmediatelyFollowedByComment}){ + if ( ${ ${ ${ ${ ${$self}{children} }[0] }{children}[-1] }{linebreaksAtEnd} }{end} + and ${ ${$self}{linebreaksAtEnd} }{end} == 0 + and defined ${ ${ ${ ${$self}{children} }[0] }{children}[-1] }{EndFinishesWithLineBreak} + and ${ ${ ${ ${$self}{children} }[0] }{children}[-1] }{EndFinishesWithLineBreak} >= 1 + and !${$self}{endImmediatelyFollowedByComment} ) + { # update the Command object - $logger->trace("Adjusting linebreaksAtEnd in command ${$self}{name}") if $is_t_switch_active; - ${${$self}{linebreaksAtEnd}}{end} = ${${${${${$self}{children}}[0]}{children}[-1]}{linebreaksAtEnd}}{end}; + $logger->trace("Adjusting linebreaksAtEnd in command ${$self}{name}") + if $is_t_switch_active; + ${ ${$self}{linebreaksAtEnd} }{end} + = ${ ${ ${ ${ ${$self}{children} }[0] }{children}[-1] }{linebreaksAtEnd} }{end}; ${$self}{replacementText} .= "\n"; # if the last argument has EndFinishesWithLineBreak == 3 - if (${${${${$self}{children}}[0]}{children}[-1]}{EndFinishesWithLineBreak} == 3 ){ - my $EndStringLogFile = ${${${${$self}{children}}[0]}{children}[-1]}{aliases}{EndFinishesWithLineBreak}||"EndFinishesWithLineBreak"; - $logger->trace("Adding another blank line to replacement text for ${$self}{name} as last argument has $EndStringLogFile == 3 ") if $is_t_switch_active; - ${$self}{replacementText} .= (${$mainSettings{modifyLineBreaks}}{preserveBlankLines}?$tokens{blanklines}:"\n")."\n"; + if ( ${ ${ ${ ${$self}{children} }[0] }{children}[-1] }{EndFinishesWithLineBreak} == 3 ) { + my $EndStringLogFile = ${ ${ ${ ${$self}{children} }[0] }{children}[-1] }{aliases}{EndFinishesWithLineBreak} + || "EndFinishesWithLineBreak"; + $logger->trace( + "Adding another blank line to replacement text for ${$self}{name} as last argument has $EndStringLogFile == 3 " + ) if $is_t_switch_active; + ${$self}{replacementText} .= ( + ${ $mainSettings{modifyLineBreaks} }{preserveBlankLines} + ? $tokens{blanklines} + : "\n" + ) . "\n"; } # update the argument object - $logger->trace("Adjusting argument object in command, ${$self}{name}") if $is_t_switch_active; - ${${${${$self}{children}}[0]}{linebreaksAtEnd}}{body} = 0; - ${${${$self}{children}}[0]}{body} =~ s/\R$//s; + $logger->trace("Adjusting argument object in command, ${$self}{name}") + if $is_t_switch_active; + ${ ${ ${ ${$self}{children} }[0] }{linebreaksAtEnd} }{body} = 0; + ${ ${ ${$self}{children} }[0] }{body} =~ s/\R$//s; # update the last mandatory/optional argument - $logger->trace("Adjusting last argument in command, ${$self}{name}") if $is_t_switch_active; - ${${${${${$self}{children}}[0]}{children}[-1]}{linebreaksAtEnd}}{end} = 0; - ${${${${$self}{children}}[0]}{children}[-1]}{EndFinishesWithLineBreak} = -1; - ${${${${$self}{children}}[0]}{children}[-1]}{replacementText} =~ s/\R$//s; + $logger->trace("Adjusting last argument in command, ${$self}{name}") + if $is_t_switch_active; + ${ ${ ${ ${ ${$self}{children} }[0] }{children}[-1] }{linebreaksAtEnd} }{end} = 0; + ${ ${ ${ ${$self}{children} }[0] }{children}[-1] }{EndFinishesWithLineBreak} = -1; + ${ ${ ${ ${$self}{children} }[0] }{children}[-1] }{replacementText} =~ s/\R$//s; # output to log file - $logger->trace(Dumper(${${${$self}{children}}[0]}{children}[-1])) if $is_tt_switch_active; + $logger->trace( Dumper( ${ ${ ${$self}{children} }[0] }{children}[-1] ) ) + if $is_tt_switch_active; } - # situation: ${${$self}{linebreaksAtEnd}}{end} == 1 and the last argument has added - # a line break, which can result in a bogus blank line (see test-cases/commands/just-one-command.tex with mand-args-mod1.yaml) - if(${${$self}{linebreaksAtEnd}}{end} == 1 - and defined ${${${${$self}{children}}[0]}{children}[-1]}{EndFinishesWithLineBreak} - and ${${${${$self}{children}}[0]}{children}[-1]}{EndFinishesWithLineBreak} >= 1 - and ${${${${$self}{children}}[0]}{children}[-1]}{replacementText}=~m/\R$/s - and !${$self}{endImmediatelyFollowedByComment}){ - +# situation: ${${$self}{linebreaksAtEnd}}{end} == 1 and the last argument has added +# a line break, which can result in a bogus blank line (see test-cases/commands/just-one-command.tex with mand-args-mod1.yaml) + if ( ${ ${$self}{linebreaksAtEnd} }{end} == 1 + and defined ${ ${ ${ ${$self}{children} }[0] }{children}[-1] }{EndFinishesWithLineBreak} + and ${ ${ ${ ${$self}{children} }[0] }{children}[-1] }{EndFinishesWithLineBreak} >= 1 + and ${ ${ ${ ${$self}{children} }[0] }{children}[-1] }{replacementText} =~ m/\R$/s + and !${$self}{endImmediatelyFollowedByComment} ) + { + # last argument adjustment - $logger->trace("Adjusting last argument in command, ${$self}{name} to avoid double line break") if $is_t_switch_active; - ${${${${$self}{children}}[0]}{children}[-1]}{replacementText}=~s/\R$//s; - ${${${${${$self}{children}}[0]}{children}[-1]}{linebreaksAtEnd}}{end} = 0; + $logger->trace("Adjusting last argument in command, ${$self}{name} to avoid double line break") + if $is_t_switch_active; + ${ ${ ${ ${$self}{children} }[0] }{children}[-1] }{replacementText} =~ s/\R$//s; + ${ ${ ${ ${ ${$self}{children} }[0] }{children}[-1] }{linebreaksAtEnd} }{end} = 0; # argument object adjustment - $logger->trace("Adjusting argument object in command, ${$self}{name} to avoid double line break") if $is_t_switch_active; - ${${${${$self}{children}}[0]}{linebreaksAtEnd}}{body} = 0; - ${${${$self}{children}}[0]}{body}=~s/\R$//s; - } + $logger->trace("Adjusting argument object in command, ${$self}{name} to avoid double line break") + if $is_t_switch_active; + ${ ${ ${ ${$self}{children} }[0] }{linebreaksAtEnd} }{body} = 0; + ${ ${ ${$self}{children} }[0] }{body} =~ s/\R$//s; + } - # the arguments body might finish with horizontal space, in which case, we need to transfer this + # the arguments body might finish with horizontal space, in which case, we need to transfer this # to the parent object replacement text. # # see ../test-cases/texexchange/5461.tex which was the first example to demonstrate the need for this - if(!${${${$self}{children}}[0]}{endImmediatelyFollowedByComment} and ${${${$self}{children}}[0]}{body} =~ m/\h*$/ and ${$self}{replacementText} !~ m/\R$/){ - $logger->trace("${$self}{name}: trailling horizontal space found in arguments -- removing it from arguments, adding to replacement text") if $is_t_switch_active; - ${${${$self}{children}}[0]}{body} =~ s/(\h*)$//s; + if ( !${ ${ ${$self}{children} }[0] }{endImmediatelyFollowedByComment} + and ${ ${ ${$self}{children} }[0] }{body} =~ m/\h*$/ + and ${$self}{replacementText} !~ m/\R$/ ) + { + $logger->trace( + "${$self}{name}: trailling horizontal space found in arguments -- removing it from arguments, adding to replacement text" + ) if $is_t_switch_active; + ${ ${ ${$self}{children} }[0] }{body} =~ s/(\h*)$//s; ${$self}{replacementText} .= "$1"; } @@ -187,12 +219,13 @@ sub tasks_particular_to_each_object{ } -sub check_linebreaks_before_equals{ +sub check_linebreaks_before_equals { + # empty routine, which allows the above routine to function (this routine kicks in for KeyEqualsValuesBraces) return; } -sub create_unique_id{ +sub create_unique_id { my $self = shift; $commandCounter++; @@ -200,13 +233,15 @@ sub create_unique_id{ return; } -sub align_at_ampersand{ +sub align_at_ampersand { + # need an empty routine here for commands; see # test-cases/matrix1.tex for example return; } -sub double_back_slash_else{ +sub double_back_slash_else { + # need an empty routine here for commands; see # test-cases/alignment/command-align.tex for example return; diff --git a/Master/texmf-dist/scripts/latexindent/LatexIndent/Document.pm b/Master/texmf-dist/scripts/latexindent/LatexIndent/Document.pm index 34eb16919b4..6a45320fe76 100644 --- a/Master/texmf-dist/scripts/latexindent/LatexIndent/Document.pm +++ b/Master/texmf-dist/scripts/latexindent/LatexIndent/Document.pm @@ -1,4 +1,5 @@ package LatexIndent::Document; + # 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 @@ -17,33 +18,41 @@ package LatexIndent::Document; use strict; use warnings; use Data::Dumper; -use File::Basename; # to get the filename and directory path +use File::Basename; # to get the filename and directory path use open ':std', ':encoding(UTF-8)'; # gain access to subroutines in the following modules -use LatexIndent::Switches qw/store_switches %switches $is_m_switch_active $is_t_switch_active $is_tt_switch_active $is_r_switch_active $is_rr_switch_active $is_rv_switch_active $is_check_switch_active/; +use LatexIndent::Switches + qw/store_switches %switches $is_m_switch_active $is_t_switch_active $is_tt_switch_active $is_r_switch_active $is_rr_switch_active $is_rv_switch_active $is_check_switch_active/; use LatexIndent::LogFile qw/process_switches $logger/; use LatexIndent::Logger qw/@logFileLines/; use LatexIndent::Check qw/simple_diff/; use LatexIndent::Lines qw/lines_body_selected_lines lines_verbatim_create_line_block/; use LatexIndent::Replacement qw/make_replacements/; -use LatexIndent::GetYamlSettings qw/yaml_read_settings yaml_modify_line_breaks_settings yaml_get_indentation_settings_for_this_object yaml_poly_switch_get_every_or_custom_value yaml_get_indentation_information yaml_get_object_attribute_for_indentation_settings yaml_alignment_at_ampersand_settings %mainSettings /; +use LatexIndent::GetYamlSettings + qw/yaml_read_settings yaml_modify_line_breaks_settings yaml_get_indentation_settings_for_this_object yaml_poly_switch_get_every_or_custom_value yaml_get_indentation_information yaml_get_object_attribute_for_indentation_settings yaml_alignment_at_ampersand_settings %mainSettings /; use LatexIndent::FileExtension qw/file_extension_check/; use LatexIndent::BackUpFileProcedure qw/create_back_up_file check_if_different/; use LatexIndent::BlankLines qw/protect_blank_lines unprotect_blank_lines condense_blank_lines/; -use LatexIndent::ModifyLineBreaks qw/modify_line_breaks_body modify_line_breaks_end modify_line_breaks_end_after remove_line_breaks_begin adjust_line_breaks_end_parent verbatim_modify_line_breaks/; +use LatexIndent::ModifyLineBreaks + qw/modify_line_breaks_body modify_line_breaks_end modify_line_breaks_end_after remove_line_breaks_begin adjust_line_breaks_end_parent verbatim_modify_line_breaks/; use LatexIndent::Sentence qw/one_sentence_per_line/; use LatexIndent::Wrap qw/text_wrap/; -use LatexIndent::TrailingComments qw/remove_trailing_comments put_trailing_comments_back_in add_comment_symbol construct_trailing_comment_regexp/; +use LatexIndent::TrailingComments + qw/remove_trailing_comments put_trailing_comments_back_in add_comment_symbol construct_trailing_comment_regexp/; use LatexIndent::HorizontalWhiteSpace qw/remove_trailing_whitespace remove_leading_space/; -use LatexIndent::Indent qw/indent wrap_up_statement determine_total_indentation indent_begin indent_body indent_end_statement final_indentation_check get_surrounding_indentation indent_children_recursively check_for_blank_lines_at_beginning put_blank_lines_back_in_at_beginning add_surrounding_indentation_to_begin_statement post_indentation_check/; +use LatexIndent::Indent + qw/indent wrap_up_statement determine_total_indentation indent_begin indent_body indent_end_statement final_indentation_check get_surrounding_indentation indent_children_recursively check_for_blank_lines_at_beginning put_blank_lines_back_in_at_beginning add_surrounding_indentation_to_begin_statement post_indentation_check/; use LatexIndent::Tokens qw/token_check %tokens/; -use LatexIndent::HiddenChildren qw/find_surrounding_indentation_for_children update_family_tree get_family_tree check_for_hidden_children hidden_children_preparation_for_alignment unpack_children_into_body/; -use LatexIndent::AlignmentAtAmpersand qw/align_at_ampersand find_aligned_block double_back_slash_else main_formatting individual_padding multicolumn_padding multicolumn_pre_check multicolumn_post_check dont_measure hidden_child_cell_row_width hidden_child_row_width /; +use LatexIndent::HiddenChildren + qw/find_surrounding_indentation_for_children update_family_tree get_family_tree check_for_hidden_children hidden_children_preparation_for_alignment unpack_children_into_body/; +use LatexIndent::AlignmentAtAmpersand + qw/align_at_ampersand find_aligned_block double_back_slash_else main_formatting individual_padding multicolumn_padding multicolumn_pre_check multicolumn_post_check dont_measure hidden_child_cell_row_width hidden_child_row_width /; use LatexIndent::DoubleBackSlash qw/dodge_double_backslash un_dodge_double_backslash/; # code blocks -use LatexIndent::Verbatim qw/put_verbatim_back_in find_verbatim_environments find_noindent_block find_verbatim_commands find_verbatim_special verbatim_common_tasks %verbatimStorage/; +use LatexIndent::Verbatim + qw/put_verbatim_back_in find_verbatim_environments find_noindent_block find_verbatim_commands find_verbatim_special verbatim_common_tasks %verbatimStorage/; use LatexIndent::Environment qw/find_environments $environmentBasicRegExp construct_environments_regexp/; use LatexIndent::IfElseFi qw/find_ifelsefi construct_ifelsefi_regexp $ifElseFiBasicRegExp/; use LatexIndent::Else qw/check_for_else_statement/; @@ -57,27 +66,30 @@ use LatexIndent::Command qw/construct_command_regexp/; use LatexIndent::KeyEqualsValuesBraces qw/construct_key_equals_values_regexp/; use LatexIndent::NamedGroupingBracesBrackets qw/construct_grouping_braces_brackets_regexp/; use LatexIndent::UnNamedGroupingBracesBrackets qw/construct_unnamed_grouping_braces_brackets_regexp/; -use LatexIndent::Special qw/find_special construct_special_begin $specialBeginAndBracesBracketsBasicRegExp $specialBeginBasicRegExp/; +use LatexIndent::Special + qw/find_special construct_special_begin $specialBeginAndBracesBracketsBasicRegExp $specialBeginBasicRegExp/; use LatexIndent::Heading qw/find_heading construct_headings_levels $allHeadingsRegexp/; use LatexIndent::FileContents qw/find_file_contents_environments_and_preamble/; use LatexIndent::Preamble; -sub new{ +sub new { + # Create new objects, with optional key/value pairs # passed as initializers. # # See Programming Perl, pg 319 my $invocant = shift; - my $class = ref($invocant) || $invocant; - my $self = {@_}; - $logger->trace(${$mainSettings{logFilePreferences}}{showDecorationStartCodeBlockTrace}) if ${$mainSettings{logFilePreferences}}{showDecorationStartCodeBlockTrace}; - bless ($self,$class); + my $class = ref($invocant) || $invocant; + my $self = {@_}; + $logger->trace( ${ $mainSettings{logFilePreferences} }{showDecorationStartCodeBlockTrace} ) + if ${ $mainSettings{logFilePreferences} }{showDecorationStartCodeBlockTrace}; + bless( $self, $class ); return $self; } -sub latexindent{ - my $self = shift; - my @fileNames = @{$_[0]}; +sub latexindent { + my $self = shift; + my @fileNames = @{ $_[0] }; my $check_switch_status_across_files = 0; @@ -86,74 +98,76 @@ sub latexindent{ # one-time operations $self->store_switches; ${$self}{fileName} = $fileNames[0]; - $self->process_switches(\@fileNames); + $self->process_switches( \@fileNames ); $self->yaml_read_settings; - ${$self}{multipleFiles} = 1 if ( (scalar (@fileNames)) >1 ); - + ${$self}{multipleFiles} = 1 if ( ( scalar(@fileNames) ) > 1 ); + my $fileCount = 0; # per-file operations foreach (@fileNames) { - $fileCount++; - if ( (scalar (@fileNames)) >1 ){ - $logger->info("*Filename: $_ (".$fileCount." of ".(scalar (@fileNames)).")") ; - } - ${$self}{fileName} = $_; - ${$self}{cruftDirectory} = $switches{cruftDirectory}||(dirname ${$self}{fileName}); - - # file existence/extension checks - my $file_existence = $self->file_extension_check; - if ($file_existence>0){ - $file_extension_status_across_files=$file_existence; - next - } - - # overwrite and overwriteIfDifferent switches, per file - ${$self}{overwrite} = $switches{overwrite}; - ${$self}{overwriteIfDifferent} = $switches{overwriteIfDifferent}; - - # the main operations - $self->operate_on_file; - - # keep track of check status across files - $check_switch_status_across_files = 1 if ($is_check_switch_active and ${$self}{originalBody} ne ${$self}{body}); + $fileCount++; + if ( ( scalar(@fileNames) ) > 1 ) { + $logger->info( "*Filename: $_ (" . $fileCount . " of " . ( scalar(@fileNames) ) . ")" ); + } + ${$self}{fileName} = $_; + ${$self}{cruftDirectory} = $switches{cruftDirectory} || ( dirname ${$self}{fileName} ); + + # file existence/extension checks + my $file_existence = $self->file_extension_check; + if ( $file_existence > 0 ) { + $file_extension_status_across_files = $file_existence; + next; + } + + # overwrite and overwriteIfDifferent switches, per file + ${$self}{overwrite} = $switches{overwrite}; + ${$self}{overwriteIfDifferent} = $switches{overwriteIfDifferent}; + + # the main operations + $self->operate_on_file; + + # keep track of check status across files + $check_switch_status_across_files = 1 + if ( $is_check_switch_active and ${$self}{originalBody} ne ${$self}{body} ); } # check switch summary across multiple files - if ( $is_check_switch_active and (scalar (@fileNames)) >1 ){ - if($check_switch_status_across_files){ - $logger->info("*check switch across multiple files: differences to report from at least one file"); - } else { - $logger->info("*check switch across multiple files: no differences to report"); - } + if ( $is_check_switch_active and ( scalar(@fileNames) ) > 1 ) { + if ($check_switch_status_across_files) { + $logger->info("*check switch across multiple files: differences to report from at least one file"); + } + else { + $logger->info("*check switch across multiple files: no differences to report"); + } } - + # logging of existence check - if ($file_extension_status_across_files>2){ - $logger->warn("*at least one of the files you specified does not exist or could not be read"); + if ( $file_extension_status_across_files > 2 ) { + $logger->warn("*at least one of the files you specified does not exist or could not be read"); } # output the log file information $self->output_logfile(); - if ($file_extension_status_across_files>2){ - exit($file_extension_status_across_files); + if ( $file_extension_status_across_files > 2 ) { + exit($file_extension_status_across_files); } # check switch active, and file changed, gives different exit code - if ($check_switch_status_across_files){ + if ($check_switch_status_across_files) { exit(1); } } -sub operate_on_file{ +sub operate_on_file { my $self = shift; $self->create_back_up_file; - $self->token_check unless ($switches{lines}) ; - $self->make_replacements(when=>"before") if ($is_r_switch_active and !$is_rv_switch_active); - unless ($is_rr_switch_active){ + $self->token_check unless ( $switches{lines} ); + $self->make_replacements( when => "before" ) if ( $is_r_switch_active and !$is_rv_switch_active ); + unless ($is_rr_switch_active) { $self->construct_regular_expressions; $self->find_noindent_block; $self->find_verbatim_commands; @@ -161,34 +175,36 @@ sub operate_on_file{ $self->remove_trailing_comments; $self->find_verbatim_environments; $self->find_verbatim_special; - $logger->trace("*Verbatim storage:") if $is_tt_switch_active; - $logger->trace(Dumper(\%verbatimStorage)) if $is_tt_switch_active; - $self->verbatim_modify_line_breaks (when=>"beforeTextWrap") if $is_m_switch_active; - $self->make_replacements(when=>"before") if $is_rv_switch_active; - $self->protect_blank_lines if $is_m_switch_active; - $self->remove_trailing_whitespace(when=>"before"); + $logger->trace("*Verbatim storage:") if $is_tt_switch_active; + $logger->trace( Dumper( \%verbatimStorage ) ) if $is_tt_switch_active; + $self->verbatim_modify_line_breaks( when => "beforeTextWrap" ) if $is_m_switch_active; + $self->make_replacements( when => "before" ) if $is_rv_switch_active; + $self->protect_blank_lines if $is_m_switch_active; + $self->remove_trailing_whitespace( when => "before" ); $self->find_file_contents_environments_and_preamble; $self->dodge_double_backslash; $self->remove_leading_space; $self->process_body_of_text; ${$self}{body} =~ s/\r\n/\n/sg if $mainSettings{dos2unixlinebreaks}; - $self->remove_trailing_whitespace(when=>"after"); - $self->condense_blank_lines if( $is_m_switch_active and ${$mainSettings{modifyLineBreaks}}{condenseMultipleBlankLinesInto} ); - $self->unprotect_blank_lines if( $is_m_switch_active and ${$mainSettings{modifyLineBreaks}}{preserveBlankLines} ); + $self->remove_trailing_whitespace( when => "after" ); + $self->condense_blank_lines + if ( $is_m_switch_active and ${ $mainSettings{modifyLineBreaks} }{condenseMultipleBlankLinesInto} ); + $self->unprotect_blank_lines + if ( $is_m_switch_active and ${ $mainSettings{modifyLineBreaks} }{preserveBlankLines} ); $self->un_dodge_double_backslash; - $self->make_replacements(when=>"after") if $is_rv_switch_active; - $self->put_verbatim_back_in (match=>"everything-except-commands"); + $self->make_replacements( when => "after" ) if $is_rv_switch_active; + $self->put_verbatim_back_in( match => "everything-except-commands" ); $self->put_trailing_comments_back_in; - $self->put_verbatim_back_in (match=>"just-commands"); - $self->make_replacements(when=>"after") if ($is_r_switch_active and !$is_rv_switch_active); - ${$self}{body} =~ s/\r\n/\n/sg if $mainSettings{dos2unixlinebreaks}; - $self->check_if_different if ${$self}{overwriteIfDifferent}; + $self->put_verbatim_back_in( match => "just-commands" ); + $self->make_replacements( when => "after" ) if ( $is_r_switch_active and !$is_rv_switch_active ); + ${$self}{body} =~ s/\r\n/\n/sg if $mainSettings{dos2unixlinebreaks}; + $self->check_if_different if ${$self}{overwriteIfDifferent}; } $self->output_indented_text; - return + return; } -sub construct_regular_expressions{ +sub construct_regular_expressions { my $self = shift; $self->construct_trailing_comment_regexp; $self->construct_environments_regexp; @@ -203,7 +219,7 @@ sub construct_regular_expressions{ $self->construct_unnamed_grouping_braces_brackets_regexp; } -sub output_indented_text{ +sub output_indented_text { my $self = shift; $self->simple_diff() if $is_check_switch_active; @@ -211,17 +227,19 @@ sub output_indented_text{ $logger->info("*Output routine:"); # if -overwrite is active then output to original fileName - if(${$self}{overwrite}){ + if ( ${$self}{overwrite} ) { $logger->info("Overwriting file ${$self}{fileName}"); - open(OUTPUTFILE,">",${$self}{fileName}); + open( OUTPUTFILE, ">", ${$self}{fileName} ); print OUTPUTFILE ${$self}{body}; close(OUTPUTFILE); - } elsif($switches{outputToFile}) { + } + elsif ( $switches{outputToFile} ) { $logger->info("Outputting to file ${$self}{outputToFile}"); - open(OUTPUTFILE,">",${$self}{outputToFile}); + open( OUTPUTFILE, ">", ${$self}{outputToFile} ); print OUTPUTFILE ${$self}{body}; close(OUTPUTFILE); - } else { + } + else { $logger->info("Not outputting to file; see -w and -o switches for more options."); } @@ -231,34 +249,36 @@ sub output_indented_text{ return; } -sub output_logfile{ - +sub output_logfile { + my $self = shift; # # put the final line in the logfile - $logger->info("${$mainSettings{logFilePreferences}}{endLogFileWith}") if ${$mainSettings{logFilePreferences}}{endLogFileWith}; - + $logger->info("${$mainSettings{logFilePreferences}}{endLogFileWith}") + if ${ $mainSettings{logFilePreferences} }{endLogFileWith}; + # github info line - $logger->info("*Please direct all communication/issues to:\nhttps://github.com/cmhughes/latexindent.pl") if ${$mainSettings{logFilePreferences}}{showGitHubInfoFooter}; + $logger->info("*Please direct all communication/issues to:\nhttps://github.com/cmhughes/latexindent.pl") + if ${ $mainSettings{logFilePreferences} }{showGitHubInfoFooter}; # open log file - my $logfileName = $switches{logFileName}||"indent.log"; + my $logfileName = $switches{logFileName} || "indent.log"; my $logfile; my $logfilePossible = 1; - open($logfile,">","${$self}{cruftDirectory}/$logfileName") or $logfilePossible =0; + open( $logfile, ">", "${$self}{cruftDirectory}/$logfileName" ) or $logfilePossible = 0; - if($logfilePossible){ - foreach my $line (@{LatexIndent::Logger::logFileLines}){ - print $logfile $line,"\n"; + if ($logfilePossible) { + foreach my $line ( @{LatexIndent::Logger::logFileLines} ) { + print $logfile $line, "\n"; } # close log file close($logfile); - } + } } -sub process_body_of_text{ +sub process_body_of_text { my $self = shift; # find objects recursively @@ -280,11 +300,12 @@ sub process_body_of_text{ return; } -sub find_objects{ +sub find_objects { my $self = shift; # one sentence per line: sentences are objects, as of V3.5.1 - $self->one_sentence_per_line if ($is_m_switch_active and ${$mainSettings{modifyLineBreaks}{oneSentencePerLine}}{manipulateSentences}); + $self->one_sentence_per_line + if ( $is_m_switch_active and ${ $mainSettings{modifyLineBreaks}{oneSentencePerLine} }{manipulateSentences} ); # text wrapping # @@ -294,15 +315,16 @@ sub find_objects{ # oneSentencePerLine: # manipulateSentences: 1 # textWrapSentences: 1 - # - if ($is_m_switch_active - and !${$mainSettings{modifyLineBreaks}{oneSentencePerLine}}{manipulateSentences} - and !${$mainSettings{modifyLineBreaks}{oneSentencePerLine}}{textWrapSentences} - and ${$mainSettings{modifyLineBreaks}{textWrapOptions}}{columns} !=0 ){ + # + if ( $is_m_switch_active + and !${ $mainSettings{modifyLineBreaks}{oneSentencePerLine} }{manipulateSentences} + and !${ $mainSettings{modifyLineBreaks}{oneSentencePerLine} }{textWrapSentences} + and ${ $mainSettings{modifyLineBreaks}{textWrapOptions} }{columns} != 0 ) + { $self->text_wrap(); # text wrapping can affect verbatim poly-switches, so we run it again - $self->verbatim_modify_line_breaks(when=>"afterTextWrap"); + $self->verbatim_modify_line_breaks( when => "afterTextWrap" ); } # search for environments @@ -318,36 +340,41 @@ sub find_objects{ $self->find_heading if ${$self}{body} =~ m/$allHeadingsRegexp/s; # the ordering of finding commands and special code blocks can change - $self->find_commands_or_key_equals_values_braces_and_special if ${$self}{body} =~ m/$specialBeginAndBracesBracketsBasicRegExp/s; - + $self->find_commands_or_key_equals_values_braces_and_special + if ${$self}{body} =~ m/$specialBeginAndBracesBracketsBasicRegExp/s; + # if there are no children, return - if(${$self}{children}){ + if ( ${$self}{children} ) { $logger->trace("*Objects have been found.") if $is_t_switch_active; - } else { + } + else { $logger->trace("No objects found."); return; } # logfile information - $logger->trace(Dumper(\%{$self})) if($is_tt_switch_active); + $logger->trace( Dumper( \%{$self} ) ) if ($is_tt_switch_active); return; } -sub find_commands_or_key_equals_values_braces_and_special{ +sub find_commands_or_key_equals_values_braces_and_special { my $self = shift; # the order in which we search for specialBeginEnd and commands/key/braces # can change depending upon specialBeforeCommand - if(${$mainSettings{specialBeginEnd}}{specialBeforeCommand}){ + if ( ${ $mainSettings{specialBeginEnd} }{specialBeforeCommand} ) { + # search for special begin/end - $logger->trace('looking for SPECIAL begin/end *before* looking for commands (see specialBeforeCommand)') if $is_t_switch_active; + $logger->trace('looking for SPECIAL begin/end *before* looking for commands (see specialBeforeCommand)') + if $is_t_switch_active; $self->find_special if ${$self}{body} =~ m/$specialBeginBasicRegExp/s; # search for commands with arguments $logger->trace('looking for COMMANDS and key = {value}') if $is_t_switch_active; $self->find_commands_or_key_equals_values_braces if ${$self}{body} =~ m/$braceBracketRegExpBasic/s; - } else { + } + else { # search for commands with arguments $logger->trace('looking for COMMANDS and key = {value}') if $is_t_switch_active; $self->find_commands_or_key_equals_values_braces if ${$self}{body} =~ m/$braceBracketRegExpBasic/s; @@ -359,63 +386,72 @@ sub find_commands_or_key_equals_values_braces_and_special{ return; } -sub tasks_particular_to_each_object{ +sub tasks_particular_to_each_object { my $self = shift; $logger->trace("There are no tasks particular to ${$self}{name}") if $is_t_switch_active; } -sub get_settings_and_store_new_object{ +sub get_settings_and_store_new_object { my $self = shift; # grab the object to be operated upon my ($latexIndentObject) = @_; # there are a number of tasks common to each object - $latexIndentObject->tasks_common_to_each_object(%{$self}); - + $latexIndentObject->tasks_common_to_each_object( %{$self} ); + # tasks particular to each object $latexIndentObject->tasks_particular_to_each_object; - + # store children in special hash - push(@{${$self}{children}},$latexIndentObject); + push( @{ ${$self}{children} }, $latexIndentObject ); # possible alignment preparation for hidden children - $self->hidden_children_preparation_for_alignment($latexIndentObject) if(${$latexIndentObject}{lookForAlignDelims} and ${$latexIndentObject}{measureHiddenChildren}); + $self->hidden_children_preparation_for_alignment($latexIndentObject) + if ( ${$latexIndentObject}{lookForAlignDelims} and ${$latexIndentObject}{measureHiddenChildren} ); - # possible decoration in log file - $logger->trace(${$mainSettings{logFilePreferences}}{showDecorationFinishCodeBlockTrace}) if ${$mainSettings{logFilePreferences}}{showDecorationFinishCodeBlockTrace}; + # possible decoration in log file + $logger->trace( ${ $mainSettings{logFilePreferences} }{showDecorationFinishCodeBlockTrace} ) + if ${ $mainSettings{logFilePreferences} }{showDecorationFinishCodeBlockTrace}; } - -sub tasks_common_to_each_object{ +sub tasks_common_to_each_object { my $self = shift; # grab the parent information my %parent = @_; # update/create the ancestor information - if($parent{ancestors}){ - $logger->trace("Ancestors *have* been found for ${$self}{name}") if($is_t_switch_active); - push(@{${$self}{ancestors}},@{$parent{ancestors}}); - } else { - $logger->trace("No ancestors found for ${$self}{name}") if($is_t_switch_active); - if(defined $parent{id} and $parent{id} ne ''){ - $logger->trace("Creating ancestors with $parent{id} as the first one") if($is_t_switch_active); - push(@{${$self}{ancestors}},{ancestorID=>$parent{id},ancestorIndentation=>\$parent{indentation},type=>"natural",name=>${$self}{name}}); - } + if ( $parent{ancestors} ) { + $logger->trace("Ancestors *have* been found for ${$self}{name}") if ($is_t_switch_active); + push( @{ ${$self}{ancestors} }, @{ $parent{ancestors} } ); + } + else { + $logger->trace("No ancestors found for ${$self}{name}") if ($is_t_switch_active); + if ( defined $parent{id} and $parent{id} ne '' ) { + $logger->trace("Creating ancestors with $parent{id} as the first one") if ($is_t_switch_active); + push( + @{ ${$self}{ancestors} }, + { ancestorID => $parent{id}, + ancestorIndentation => \$parent{indentation}, + type => "natural", + name => ${$self}{name} + } + ); + } } # natural ancestors ${$self}{naturalAncestors} = q(); - if(${$self}{ancestors}){ - ${$self}{naturalAncestors} .= "---".${$_}{ancestorID}."\n" for @{${$self}{ancestors}}; + if ( ${$self}{ancestors} ) { + ${$self}{naturalAncestors} .= "---" . ${$_}{ancestorID} . "\n" for @{ ${$self}{ancestors} }; } # in what follows, $self can be an environment, ifElseFi, etc # count linebreaks in body my $bodyLineBreaks = 0; - $bodyLineBreaks++ while(${$self}{body} =~ m/\R/sxg); + $bodyLineBreaks++ while ( ${$self}{body} =~ m/\R/sxg ); ${$self}{bodyLineBreaks} = $bodyLineBreaks; # get settings for this object @@ -430,10 +466,11 @@ sub tasks_common_to_each_object{ # text wrapping can make the ID split across lines ${$self}{idRegExp} = ${$self}{id}; - if($is_m_switch_active - and ${$mainSettings{modifyLineBreaks}{textWrapOptions}}{huge} ne "overflow"){ - my $IDwithLineBreaks = join("\\R?\\h*",split(//,${$self}{id})); - ${$self}{idRegExp} = qr/$IDwithLineBreaks/s; + if ( $is_m_switch_active + and ${ $mainSettings{modifyLineBreaks}{textWrapOptions} }{huge} ne "overflow" ) + { + my $IDwithLineBreaks = join( "\\R?\\h*", split( //, ${$self}{id} ) ); + ${$self}{idRegExp} = qr/$IDwithLineBreaks/s; } # the replacement text can be just the ID, but the ID might have a line break at the end of it @@ -444,25 +481,30 @@ sub tasks_common_to_each_object{ $self->adjust_replacement_text_line_breaks_at_end; # modify line breaks on body and end statements - $self->modify_line_breaks_body if ($is_m_switch_active and defined ${$self}{BodyStartsOnOwnLine} and ${$self}{BodyStartsOnOwnLine}!=0); + $self->modify_line_breaks_body + if ( $is_m_switch_active and defined ${$self}{BodyStartsOnOwnLine} and ${$self}{BodyStartsOnOwnLine} != 0 ); # modify line breaks end statements - $self->modify_line_breaks_end if ($is_m_switch_active and defined ${$self}{EndStartsOnOwnLine} and ${$self}{EndStartsOnOwnLine}!=0); - $self->modify_line_breaks_end_after if ($is_m_switch_active and defined ${$self}{EndFinishesWithLineBreak} and ${$self}{EndFinishesWithLineBreak}!=0); + $self->modify_line_breaks_end + if ( $is_m_switch_active and defined ${$self}{EndStartsOnOwnLine} and ${$self}{EndStartsOnOwnLine} != 0 ); + $self->modify_line_breaks_end_after + if ($is_m_switch_active + and defined ${$self}{EndFinishesWithLineBreak} + and ${$self}{EndFinishesWithLineBreak} != 0 ); # check the body for current children $self->check_for_hidden_children if ${$self}{body} =~ m/$tokens{beginOfToken}/; # double back slash poly-switch check - $self->double_back_slash_else if ($is_m_switch_active and ${$self}{lookForAlignDelims}); - + $self->double_back_slash_else if ( $is_m_switch_active and ${$self}{lookForAlignDelims} ); + # some objects can format their body to align at the & character - $self->align_at_ampersand if (${$self}{lookForAlignDelims} and !${$self}{measureHiddenChildren}); + $self->align_at_ampersand if ( ${$self}{lookForAlignDelims} and !${$self}{measureHiddenChildren} ); return; } -sub get_replacement_text{ +sub get_replacement_text { my $self = shift; # the replacement text can be just the ID, but the ID might have a line break at the end of it @@ -470,41 +512,45 @@ sub get_replacement_text{ return; } -sub adjust_replacement_text_line_breaks_at_end{ +sub adjust_replacement_text_line_breaks_at_end { my $self = shift; # the above regexp, when used below, will remove the trailing linebreak in ${$self}{linebreaksAtEnd}{end} # so we compensate for it here - $logger->trace("Putting linebreak after replacementText for ${$self}{name}") if($is_t_switch_active); - if(defined ${$self}{horizontalTrailingSpace}){ - ${$self}{replacementText} .= ${$self}{horizontalTrailingSpace} unless(!${$self}{endImmediatelyFollowedByComment} and defined ${$self}{EndFinishesWithLineBreak} and ${$self}{EndFinishesWithLineBreak}==2); + $logger->trace("Putting linebreak after replacementText for ${$self}{name}") if ($is_t_switch_active); + if ( defined ${$self}{horizontalTrailingSpace} ) { + ${$self}{replacementText} .= ${$self}{horizontalTrailingSpace} + unless ( !${$self}{endImmediatelyFollowedByComment} + and defined ${$self}{EndFinishesWithLineBreak} + and ${$self}{EndFinishesWithLineBreak} == 2 ); } - ${$self}{replacementText} .= "\n" if(${$self}{linebreaksAtEnd}{end}); + ${$self}{replacementText} .= "\n" if ( ${$self}{linebreaksAtEnd}{end} ); } -sub count_body_line_breaks{ +sub count_body_line_breaks { my $self = shift; - my $oldBodyLineBreaks = (defined ${$self}{bodyLineBreaks})? ${$self}{bodyLineBreaks} : 0; + my $oldBodyLineBreaks = ( defined ${$self}{bodyLineBreaks} ) ? ${$self}{bodyLineBreaks} : 0; # count linebreaks in body my $bodyLineBreaks = 0; - $bodyLineBreaks++ while(${$self}{body} =~ m/\R/sxg); + $bodyLineBreaks++ while ( ${$self}{body} =~ m/\R/sxg ); ${$self}{bodyLineBreaks} = $bodyLineBreaks; - $logger->trace("bodyLineBreaks ${$self}{bodyLineBreaks}") if((${$self}{bodyLineBreaks} != $oldBodyLineBreaks) and $is_t_switch_active); + $logger->trace("bodyLineBreaks ${$self}{bodyLineBreaks}") + if ( ( ${$self}{bodyLineBreaks} != $oldBodyLineBreaks ) and $is_t_switch_active ); } -sub wrap_up_tasks{ +sub wrap_up_tasks { my $self = shift; # most recent child object - my $child = @{${$self}{children}}[-1]; + my $child = @{ ${$self}{children} }[-1]; # check if the last object was the last thing in the body, and if it has adjusted linebreaks $self->adjust_line_breaks_end_parent if $is_m_switch_active; - $logger->trace(Dumper(\%{$child})) if($is_tt_switch_active); + $logger->trace( Dumper( \%{$child} ) ) if ($is_tt_switch_active); $logger->trace("replaced with ID: ${$child}{id}") if $is_t_switch_active; } diff --git a/Master/texmf-dist/scripts/latexindent/LatexIndent/DoubleBackSlash.pm b/Master/texmf-dist/scripts/latexindent/LatexIndent/DoubleBackSlash.pm index 8b8be3e25ec..1c483b68655 100644 --- a/Master/texmf-dist/scripts/latexindent/LatexIndent/DoubleBackSlash.pm +++ b/Master/texmf-dist/scripts/latexindent/LatexIndent/DoubleBackSlash.pm @@ -1,4 +1,5 @@ package LatexIndent::DoubleBackSlash; + # 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 @@ -25,9 +26,9 @@ our @EXPORT_OK = qw/dodge_double_backslash un_dodge_double_backslash/; # cycle list={blue,mark=none\\}, # see test-cases/texexchange/29293-christian-feuersanger.tex # -# This is problematic, as the argument regexp won't count the right } because it has a +# This is problematic, as the argument regexp won't count the right } because it has a # backslash immediately infront of it! -sub dodge_double_backslash{ +sub dodge_double_backslash { my $self = shift; ${$self}{body} =~ s/(?:\\\\(\{|\}|\]))/$tokens{doubleBackSlash}$1/sg; @@ -35,7 +36,7 @@ sub dodge_double_backslash{ } # this routine replaces the token with the \\\\ -sub un_dodge_double_backslash{ +sub un_dodge_double_backslash { my $self = shift; ${$self}{body} =~ s/$tokens{doubleBackSlash}/\\\\/sg; diff --git a/Master/texmf-dist/scripts/latexindent/LatexIndent/Else.pm b/Master/texmf-dist/scripts/latexindent/LatexIndent/Else.pm index a213d7b247c..54de7808c45 100644 --- a/Master/texmf-dist/scripts/latexindent/LatexIndent/Else.pm +++ b/Master/texmf-dist/scripts/latexindent/LatexIndent/Else.pm @@ -1,4 +1,5 @@ package LatexIndent::Else; + # 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 @@ -24,11 +25,11 @@ use LatexIndent::Braces qw/$braceBracketRegExpBasic/; use LatexIndent::Special qw/$specialBeginAndBracesBracketsBasicRegExp/; use LatexIndent::Heading qw/$allHeadingsRegexp/; use Exporter qw/import/; -our @ISA = "LatexIndent::Document"; # class inheritance, Programming Perl, pg 321 +our @ISA = "LatexIndent::Document"; # class inheritance, Programming Perl, pg 321 our @EXPORT_OK = qw/check_for_else_statement/; our $elseCounter; -sub check_for_else_statement{ +sub check_for_else_statement { my $self = shift; # we call the else routine from different places; see IfElseFi.pm and Special.pm @@ -51,7 +52,7 @@ sub check_for_else_statement{ $logger->trace("*Looking for $input{elseNameRegExp} statement (${$self}{name})") if $is_t_switch_active; - while(${$self}{body} =~ m/$elseRegExp(\h*)($trailingCommentRegExp)?/){ + while ( ${$self}{body} =~ m/$elseRegExp(\h*)($trailingCommentRegExp)?/ ) { ${$self}{body} =~ s/$elseRegExp(\h*)($trailingCommentRegExp)? / # create a new Else object @@ -91,41 +92,44 @@ sub check_for_else_statement{ return; } -sub remove_line_breaks_begin{ +sub remove_line_breaks_begin { + # the \else command can need a trailing white space if the line breaks have been removed after it and # there is no white space - my $self = shift; - my $BodyStringLogFile = ${$self}{aliases}{BodyStartsOnOwnLine}||"BodyStartsOnOwnLine"; + my $self = shift; + my $BodyStringLogFile = ${$self}{aliases}{BodyStartsOnOwnLine} || "BodyStartsOnOwnLine"; $logger->trace("Removing linebreak at the end of begin (see $BodyStringLogFile)"); ${$self}{begin} =~ s/\R*$//sx; - ${$self}{begin} .= " " unless(${$self}{begin} =~ m/\h$/s or ${$self}{body} =~ m/^\h/s or ${$self}{body} =~ m/^\R/s ); + ${$self}{begin} .= " " + unless ( ${$self}{begin} =~ m/\h$/s or ${$self}{body} =~ m/^\h/s or ${$self}{body} =~ m/^\R/s ); ${$self}{linebreaksAtEnd}{begin} = 0; } -sub tasks_particular_to_each_object{ +sub tasks_particular_to_each_object { my $self = shift; # search for headings (important to do this before looking for commands!) $self->find_heading if ${$self}{body} =~ m/$allHeadingsRegexp/s; # search for commands and special code blocks - $self->find_commands_or_key_equals_values_braces_and_special if ${$self}{body} =~ m/$specialBeginAndBracesBracketsBasicRegExp/s; - + $self->find_commands_or_key_equals_values_braces_and_special + if ${$self}{body} =~ m/$specialBeginAndBracesBracketsBasicRegExp/s; + # search for arguments $self->find_opt_mand_arguments if ${$self}{body} =~ m/$braceBracketRegExpBasic/s; return; } -sub yaml_get_indentation_information{ +sub yaml_get_indentation_information { return q(); } -sub check_for_hidden_children{ +sub check_for_hidden_children { return q(); } -sub create_unique_id{ +sub create_unique_id { my $self = shift; $elseCounter++; diff --git a/Master/texmf-dist/scripts/latexindent/LatexIndent/Environment.pm b/Master/texmf-dist/scripts/latexindent/LatexIndent/Environment.pm index 0f51dfec567..9cb9850d2b4 100755 --- a/Master/texmf-dist/scripts/latexindent/LatexIndent/Environment.pm +++ b/Master/texmf-dist/scripts/latexindent/LatexIndent/Environment.pm @@ -1,4 +1,5 @@ package LatexIndent::Environment; + # 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 @@ -26,17 +27,17 @@ use LatexIndent::IfElseFi qw/$ifElseFiBasicRegExp/; use LatexIndent::Heading qw/$allHeadingsRegexp/; use LatexIndent::Special qw/$specialBeginAndBracesBracketsBasicRegExp/; use Exporter qw/import/; -our @ISA = "LatexIndent::Document"; # class inheritance, Programming Perl, pg 321 +our @ISA = "LatexIndent::Document"; # class inheritance, Programming Perl, pg 321 our @EXPORT_OK = qw/find_environments $environmentBasicRegExp construct_environments_regexp/; our $environmentCounter; our $environmentBasicRegExp = qr/\\begin\{/; our $environmentRegExp; # store the regular expresssion for matching and replacing the \begin{}...\end{} statements -sub construct_environments_regexp{ - +sub construct_environments_regexp { + # read from fine tuning - my $environmentNameRegExp = qr/${${$mainSettings{fineTuning}}{environments}}{name}/; + my $environmentNameRegExp = qr/${${$mainSettings{fineTuning}}{environments}}{name}/; $environmentRegExp = qr/ ( \\begin\{ @@ -63,14 +64,13 @@ sub construct_environments_regexp{ /sx; } -sub find_environments{ +sub find_environments { my $self = shift; + while ( ${$self}{body} =~ m/$environmentRegExp\h*($trailingCommentRegExp)?/ ) { - while( ${$self}{body} =~ m/$environmentRegExp\h*($trailingCommentRegExp)?/){ - - # global substitution - ${$self}{body} =~ s/ + # global substitution + ${$self}{body} =~ s/ $environmentRegExp(\h*)($trailingCommentRegExp)? / # create a new Environment object @@ -95,36 +95,40 @@ sub find_environments{ $self->get_settings_and_store_new_object($env); ${@{${$self}{children}}[-1]}{replacementText}.($9?$9:q()).($10?$10:q()); /xseg; - $self->adjust_line_breaks_end_parent if $is_m_switch_active; - } + $self->adjust_line_breaks_end_parent if $is_m_switch_active; + } return; } -sub tasks_particular_to_each_object{ +sub tasks_particular_to_each_object { my $self = shift; # if the environment is empty, we may need to update linebreaksAtEnd{body} - if(${$self}{body} =~ m/^\h*$/s and ${${$self}{linebreaksAtEnd}}{begin}){ - $logger->trace("empty environment body (${$self}{name}), updating linebreaksAtEnd{body} to be 1") if($is_t_switch_active); - ${${$self}{linebreaksAtEnd}}{body} = 1; + if ( ${$self}{body} =~ m/^\h*$/s and ${ ${$self}{linebreaksAtEnd} }{begin} ) { + $logger->trace("empty environment body (${$self}{name}), updating linebreaksAtEnd{body} to be 1") + if ($is_t_switch_active); + ${ ${$self}{linebreaksAtEnd} }{body} = 1; } # lookForAlignDelims: lookForChildCodeBlocks set to 0 means no child objects searched for # see: test-cases/alignment/issue-308.tex # - if( defined ${$self}{lookForChildCodeBlocks} and !${$self}{lookForChildCodeBlocks} ){ - $logger->trace("lookForAlignDelims: lookForChildCodeBlocks set to 0, so child objects will *NOT* be searched for") if($is_t_switch_active); - return; + if ( defined ${$self}{lookForChildCodeBlocks} and !${$self}{lookForChildCodeBlocks} ) { + $logger->trace( + "lookForAlignDelims: lookForChildCodeBlocks set to 0, so child objects will *NOT* be searched for") + if ($is_t_switch_active); + return; } # search for items as the first order of business - $self->find_items if ${$mainSettings{indentAfterItems}}{${$self}{name}}; + $self->find_items if ${ $mainSettings{indentAfterItems} }{ ${$self}{name} }; # search for headings (important to do this before looking for commands!) $self->find_heading if ${$self}{body} =~ m/$allHeadingsRegexp/s; # search for commands and special code blocks - $self->find_commands_or_key_equals_values_braces_and_special if ${$self}{body} =~ m/$specialBeginAndBracesBracketsBasicRegExp/s; + $self->find_commands_or_key_equals_values_braces_and_special + if ${$self}{body} =~ m/$specialBeginAndBracesBracketsBasicRegExp/s; # search for arguments $self->find_opt_mand_arguments if ${$self}{body} =~ m/$braceBracketRegExpBasic/s; @@ -134,7 +138,7 @@ sub tasks_particular_to_each_object{ } -sub create_unique_id{ +sub create_unique_id { my $self = shift; $environmentCounter++; @@ -142,5 +146,4 @@ sub create_unique_id{ return; } - 1; diff --git a/Master/texmf-dist/scripts/latexindent/LatexIndent/FileContents.pm b/Master/texmf-dist/scripts/latexindent/LatexIndent/FileContents.pm index 4683cc7a119..5093458ee6f 100644 --- a/Master/texmf-dist/scripts/latexindent/LatexIndent/FileContents.pm +++ b/Master/texmf-dist/scripts/latexindent/LatexIndent/FileContents.pm @@ -1,4 +1,5 @@ package LatexIndent::FileContents; + # 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 @@ -28,23 +29,23 @@ use LatexIndent::Verbatim qw/%verbatimStorage/; use Data::Dumper; use Exporter qw/import/; our @EXPORT_OK = qw/find_file_contents_environments_and_preamble/; -our @ISA = "LatexIndent::Document"; # class inheritance, Programming Perl, pg 321 +our @ISA = "LatexIndent::Document"; # class inheritance, Programming Perl, pg 321 our $fileContentsCounter; -sub find_file_contents_environments_and_preamble{ +sub find_file_contents_environments_and_preamble { my $self = shift; - # store the file contents blocks in an array which, depending on the value - # of indentPreamble, will be put into the verbatim hash, or otherwise + # store the file contents blocks in an array which, depending on the value + # of indentPreamble, will be put into the verbatim hash, or otherwise # stored as children to be operated upon - my @fileContentsStorageArray; + my @fileContentsStorageArray; # fileContents environments $logger->trace('*Searching for FILE CONTENTS environments (see fileContentsEnvironments)') if $is_t_switch_active; - $logger->trace(Dumper(\%{$mainSettings{fileContentsEnvironments}})) if($is_tt_switch_active); - while( my ($fileContentsEnv,$yesno)= each %{$mainSettings{fileContentsEnvironments}}){ + $logger->trace( Dumper( \%{ $mainSettings{fileContentsEnvironments} } ) ) if ($is_tt_switch_active); + while ( my ( $fileContentsEnv, $yesno ) = each %{ $mainSettings{fileContentsEnvironments} } ) { - if(!$yesno){ + if ( !$yesno ) { $logger->trace(" *not* looking for $fileContentsEnv as $fileContentsEnv:$yesno"); next; } @@ -52,7 +53,7 @@ sub find_file_contents_environments_and_preamble{ $logger->trace("looking for $fileContentsEnv environments") if $is_t_switch_active; # the trailing * needs some care - if($fileContentsEnv =~ m/\*$/){ + if ( $fileContentsEnv =~ m/\*$/ ) { $fileContentsEnv =~ s/\*$//; $fileContentsEnv .= '\*'; } @@ -73,52 +74,54 @@ sub find_file_contents_environments_and_preamble{ (\R)? # possibly followed by a line break /sx; - while( ${$self}{body} =~ m/$fileContentsRegExp/sx){ - - # create a new Environment object - my $fileContentsBlock = LatexIndent::FileContents->new( begin=>$1, - body=>$3, - end=>$4, - name=>$2, - linebreaksAtEnd=>{ - begin=>0, - body=>0, - end=>$5?1:0, - }, - modifyLineBreaksYamlName=>"filecontents", - ); - # give unique id - $fileContentsBlock->create_unique_id; - - # text wrapping can make the ID split across lines - ${$fileContentsBlock}{idRegExp} = ${$fileContentsBlock}{id}; - - if($is_m_switch_active and ${$mainSettings{modifyLineBreaks}{textWrapOptions}}{huge} ne "overflow"){ - my $IDwithLineBreaks = join("\\R?\\h*",split(//,${$fileContentsBlock}{id})); - ${$fileContentsBlock}{idRegExp} = qr/$IDwithLineBreaks/s; - } - - # the replacement text can be just the ID, but the ID might have a line break at the end of it - $fileContentsBlock->get_replacement_text; - - # count body line breaks - $fileContentsBlock->count_body_line_breaks; - - # the above regexp, when used below, will remove the trailing linebreak in ${$self}{linebreaksAtEnd}{end} - # so we compensate for it here - $fileContentsBlock->adjust_replacement_text_line_breaks_at_end; - - # store the fileContentsBlock, and determine location afterwards - push(@fileContentsStorageArray,$fileContentsBlock); - - # log file output - $logger->trace("FILECONTENTS environment found: ${$fileContentsBlock}{name}")if $is_t_switch_active; - - # remove the environment block, and replace with unique ID - ${$self}{body} =~ s/$fileContentsRegExp/${$fileContentsBlock}{replacementText}/sx; - - $logger->trace("replaced with ID: ${$fileContentsBlock}{id}") if $is_tt_switch_active; - } + while ( ${$self}{body} =~ m/$fileContentsRegExp/sx ) { + + # create a new Environment object + my $fileContentsBlock = LatexIndent::FileContents->new( + begin => $1, + body => $3, + end => $4, + name => $2, + linebreaksAtEnd => { + begin => 0, + body => 0, + end => $5 ? 1 : 0, + }, + modifyLineBreaksYamlName => "filecontents", + ); + + # give unique id + $fileContentsBlock->create_unique_id; + + # text wrapping can make the ID split across lines + ${$fileContentsBlock}{idRegExp} = ${$fileContentsBlock}{id}; + + if ( $is_m_switch_active and ${ $mainSettings{modifyLineBreaks}{textWrapOptions} }{huge} ne "overflow" ) { + my $IDwithLineBreaks = join( "\\R?\\h*", split( //, ${$fileContentsBlock}{id} ) ); + ${$fileContentsBlock}{idRegExp} = qr/$IDwithLineBreaks/s; + } + + # the replacement text can be just the ID, but the ID might have a line break at the end of it + $fileContentsBlock->get_replacement_text; + + # count body line breaks + $fileContentsBlock->count_body_line_breaks; + + # the above regexp, when used below, will remove the trailing linebreak in ${$self}{linebreaksAtEnd}{end} + # so we compensate for it here + $fileContentsBlock->adjust_replacement_text_line_breaks_at_end; + + # store the fileContentsBlock, and determine location afterwards + push( @fileContentsStorageArray, $fileContentsBlock ); + + # log file output + $logger->trace("FILECONTENTS environment found: ${$fileContentsBlock}{name}") if $is_t_switch_active; + + # remove the environment block, and replace with unique ID + ${$self}{body} =~ s/$fileContentsRegExp/${$fileContentsBlock}{replacementText}/sx; + + $logger->trace("replaced with ID: ${$fileContentsBlock}{id}") if $is_tt_switch_active; + } } # determine if body of document contains \begin{document} -- if it does, then assume @@ -133,33 +136,36 @@ sub find_file_contents_environments_and_preamble{ my $needToStorePreamble = 0; # try and find the preamble - if( ${$self}{body} =~ m/$preambleRegExp/sx and ${$mainSettings{lookForPreamble}}{${$self}{fileExtension}}){ + if ( ${$self}{body} =~ m/$preambleRegExp/sx and ${ $mainSettings{lookForPreamble} }{ ${$self}{fileExtension} } ) { - $logger->trace("\\begin{document} found in body (after searching for filecontents)-- assuming that a preamble exists") if $is_t_switch_active ; + $logger->trace( + "\\begin{document} found in body (after searching for filecontents)-- assuming that a preamble exists") + if $is_t_switch_active; # create a preamble object - $preamble = LatexIndent::Preamble->new( begin=>q(), - body=>$1, - end=>q(), - name=>"preamble", - linebreaksAtEnd=>{ - begin=>0, - body=>$2?1:0, - end=>0, - }, - afterbit=>($2?$2:q())."\\begin{document}", - modifyLineBreaksYamlName=>"preamble", - ); + $preamble = LatexIndent::Preamble->new( + begin => q(), + body => $1, + end => q(), + name => "preamble", + linebreaksAtEnd => { + begin => 0, + body => $2 ? 1 : 0, + end => 0, + }, + afterbit => ( $2 ? $2 : q() ) . "\\begin{document}", + modifyLineBreaksYamlName => "preamble", + ); # give unique id $preamble->create_unique_id; - + # text wrapping can make the ID split across lines ${$preamble}{idRegExp} = ${$preamble}{id}; - if($is_m_switch_active and ${$mainSettings{modifyLineBreaks}{textWrapOptions}}{huge} ne "overflow"){ - my $IDwithLineBreaks = join("\\R?\\h*",split(//,${$preamble}{id})); - ${$preamble}{idRegExp} = qr/$IDwithLineBreaks/s; + if ( $is_m_switch_active and ${ $mainSettings{modifyLineBreaks}{textWrapOptions} }{huge} ne "overflow" ) { + my $IDwithLineBreaks = join( "\\R?\\h*", split( //, ${$preamble}{id} ) ); + ${$preamble}{idRegExp} = qr/$IDwithLineBreaks/s; } # get the replacement_text @@ -172,64 +178,79 @@ sub find_file_contents_environments_and_preamble{ ${$self}{body} =~ s/$preambleRegExp/${$preamble}{replacementText}/sx; $logger->trace("replaced with ID: ${$preamble}{replacementText}") if $is_tt_switch_active; + # indentPreamble set to 1 - if($mainSettings{indentPreamble}){ + if ( $mainSettings{indentPreamble} ) { $logger->trace("storing ${$preamble}{id} for indentation (see indentPreamble)") if $is_tt_switch_active; $needToStorePreamble = 1; - } else { + } + else { # indentPreamble set to 0 - $logger->trace("NOT storing ${$preamble}{id} for indentation -- will store as VERBATIM object (because indentPreamble:0)") if $is_t_switch_active; - $preamble->unprotect_blank_lines if( $is_m_switch_active and ${$mainSettings{modifyLineBreaks}}{preserveBlankLines} ); - $verbatimStorage{${$preamble}{id}} = $preamble; + $logger->trace( + "NOT storing ${$preamble}{id} for indentation -- will store as VERBATIM object (because indentPreamble:0)" + ) if $is_t_switch_active; + $preamble->unprotect_blank_lines + if ( $is_m_switch_active and ${ $mainSettings{modifyLineBreaks} }{preserveBlankLines} ); + $verbatimStorage{ ${$preamble}{id} } = $preamble; } - } else { + } + else { ${$self}{preamblePresent} = 0; } # loop through the fileContents array, check if it's in the preamble - foreach(@fileContentsStorageArray){ - my $indentThisChild = 0; - # verbatim children go in special hash - if($preamble ne '' and ${$preamble}{body} =~ m/${$_}{id}/){ - $logger->trace("filecontents (${$_}{id}) is within preamble") if $is_t_switch_active; - # indentPreamble set to 1 - if($mainSettings{indentPreamble}){ - $logger->trace("storing ${$_}{id} for indentation (indentPreamble is 1)") if $is_t_switch_active; - $indentThisChild = 1; - } else { - # indentPreamble set to 0 - $logger->trace("Storing ${$_}{id} as a VERBATIM object (indentPreamble is 0)") if $is_t_switch_active; - $verbatimStorage{${$_}{id}} = $_; - } - } else { - $logger->trace("storing ${$_}{id} for indentation (${$_}{name} found outside of preamble)") if $is_t_switch_active; - $indentThisChild = 1; - } - # store the child, if necessary - if($indentThisChild){ - $_->remove_leading_space; - $_->yaml_get_indentation_settings_for_this_object; - $_->tasks_particular_to_each_object; - push(@{${$self}{children}},$_); - - # possible decoration in log file - $logger->trace(${$mainSettings{logFilePreferences}}{showDecorationFinishCodeBlockTrace}) if ${$mainSettings{logFilePreferences}}{showDecorationFinishCodeBlockTrace}; - } + foreach (@fileContentsStorageArray) { + my $indentThisChild = 0; + + # verbatim children go in special hash + if ( $preamble ne '' and ${$preamble}{body} =~ m/${$_}{id}/ ) { + $logger->trace("filecontents (${$_}{id}) is within preamble") if $is_t_switch_active; + + # indentPreamble set to 1 + if ( $mainSettings{indentPreamble} ) { + $logger->trace("storing ${$_}{id} for indentation (indentPreamble is 1)") if $is_t_switch_active; + $indentThisChild = 1; + } + else { + # indentPreamble set to 0 + $logger->trace("Storing ${$_}{id} as a VERBATIM object (indentPreamble is 0)") if $is_t_switch_active; + $verbatimStorage{ ${$_}{id} } = $_; + } + } + else { + $logger->trace("storing ${$_}{id} for indentation (${$_}{name} found outside of preamble)") + if $is_t_switch_active; + $indentThisChild = 1; + } + + # store the child, if necessary + if ($indentThisChild) { + $_->remove_leading_space; + $_->yaml_get_indentation_settings_for_this_object; + $_->tasks_particular_to_each_object; + push( @{ ${$self}{children} }, $_ ); + + # possible decoration in log file + $logger->trace( ${ $mainSettings{logFilePreferences} }{showDecorationFinishCodeBlockTrace} ) + if ${ $mainSettings{logFilePreferences} }{showDecorationFinishCodeBlockTrace}; + } } - if($needToStorePreamble){ + if ($needToStorePreamble) { $preamble->dodge_double_backslash; $preamble->remove_leading_space; + # text wrapping - $preamble->text_wrap() if ($is_m_switch_active and ${$mainSettings{modifyLineBreaks}{textWrapOptions}}{columns} !=0 ); - $preamble->find_commands_or_key_equals_values_braces if($mainSettings{preambleCommandsBeforeEnvironments}); + $preamble->text_wrap() + if ( $is_m_switch_active and ${ $mainSettings{modifyLineBreaks}{textWrapOptions} }{columns} != 0 ); + $preamble->find_commands_or_key_equals_values_braces if ( $mainSettings{preambleCommandsBeforeEnvironments} ); $preamble->tasks_particular_to_each_object; - push(@{${$self}{children}},$preamble); + push( @{ ${$self}{children} }, $preamble ); } return; } -sub create_unique_id{ +sub create_unique_id { my $self = shift; $fileContentsCounter++; @@ -237,7 +258,7 @@ sub create_unique_id{ return; } -sub tasks_particular_to_each_object{ +sub tasks_particular_to_each_object { my $self = shift; # search for environments @@ -248,9 +269,10 @@ sub tasks_particular_to_each_object{ # search for headings (part, chapter, section, setc) $self->find_heading if ${$self}{body} =~ m/$allHeadingsRegexp/s; - + # search for commands and special code blocks - $self->find_commands_or_key_equals_values_braces_and_special if ${$self}{body} =~ m/$specialBeginAndBracesBracketsBasicRegExp/s; + $self->find_commands_or_key_equals_values_braces_and_special + if ${$self}{body} =~ m/$specialBeginAndBracesBracketsBasicRegExp/s; } 1; diff --git a/Master/texmf-dist/scripts/latexindent/LatexIndent/FileExtension.pm b/Master/texmf-dist/scripts/latexindent/LatexIndent/FileExtension.pm index 6dc2b696412..8b01fa9e299 100644 --- a/Master/texmf-dist/scripts/latexindent/LatexIndent/FileExtension.pm +++ b/Master/texmf-dist/scripts/latexindent/LatexIndent/FileExtension.pm @@ -1,4 +1,5 @@ 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 @@ -18,133 +19,144 @@ use strict; use warnings; use PerlIO::encoding; use open ':std', ':encoding(UTF-8)'; -use File::Basename; # to get the filename and directory path +use File::Basename; # to get the filename and directory path use Exporter qw/import/; 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/; -sub file_extension_check{ +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/\..[^.]*$/); - + my ( $name, $dir, $ext ) = fileparse( $fileName, qr/\..[^.]*$/ ); + # grab the file extension preferences - my %fileExtensionPreference= %{$mainSettings{fileExtensionPreference}}; + my %fileExtensionPreference = %{ $mainSettings{fileExtensionPreference} }; + + # sort the file extensions by preference + my @fileExtensions + = sort { $fileExtensionPreference{$a} <=> $fileExtensionPreference{$b} } keys(%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) { + 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)); + $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 ( -e $fileName.$_ ) { - $logger->info("$fileName$_ found!"); - $fileName .= $_; - $logger->info("Updated fileName to $fileName"); - ${$self}{fileName} = $fileName ; - $fileFound = 1; - $ext = $_; - last; + foreach (@fileExtensions) { + if ( -e $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 indendation 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$_"); + 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 indendation 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 indendation done."); + $self->output_logfile(); + exit(3); } - $logger->fatal("but couldn't find any of them.\nConsider updating fileExtensionPreference."); - $logger->fatal("*Exiting, no indendation done."); - $self->output_logfile(); - exit(3); - } } - } else { + } + else { # if the file has a recognised extension, check that the file exists - unless( -e $fileName ){ - if (defined ${$self}{multipleFiles}){ - $logger->warn("*I couldn't find $fileName, are you sure it exists?"); - $logger->warn("moving on, no indendation done for ${$self}{fileName}."); - return 3; - } else { - $logger->fatal("*I couldn't find $fileName, are you sure it exists?"); - $logger->fatal("Exiting, no indendation done."); - $self->output_logfile(); - exit(3); - } + unless ( -e $fileName ) { + if ( defined ${$self}{multipleFiles} ) { + $logger->warn("*I couldn't find $fileName, are you sure it exists?"); + $logger->warn("moving on, no indendation done for ${$self}{fileName}."); + return 3; + } + else { + $logger->fatal("*I couldn't find $fileName, are you sure it exists?"); + $logger->fatal("Exiting, no indendation done."); + $self->output_logfile(); + exit(3); + } } - } - } + } + } # store the file extension ${$self}{fileExtension} = $ext; # check to see if -o switch is active - if($switches{outputToFile}){ - + if ( $switches{outputToFile} ) { + $logger->info("*-o switch active: output file check"); ${$self}{outputToFile} = $switches{outputToFile}; - if ($fileName eq "-" and $switches{outputToFile} =~ m/^\+/){ + 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 "+"){ + if ( $switches{outputToFile} =~ m/^\+(.*)/ and $1 ne "+" ) { $logger->info("-o switch called with + symbol at the beginning: ${$self}{outputToFile}"); - ${$self}{outputToFile} = ${$self}{baseName}.$1; + ${$self}{outputToFile} = ${$self}{baseName} . $1; $logger->info("output file is now: ${$self}{outputToFile}"); } my $strippedFileExtension = ${$self}{fileExtension}; - $strippedFileExtension =~ s/\.//; - $strippedFileExtension = "tex" if ($strippedFileExtension eq ""); + $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); + 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){ + 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"); + ${$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, + # 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/\+\+$/){ + if ( $name =~ m/\+\+$/ ) { $logger->info("-o switch called with file name ending with ++: ${$self}{outputToFile}"); $name =~ s/\+\+$//; - $name = ${$self}{baseName} if ($name eq ""); + $name = ${$self}{baseName} if ( $name eq "" ); my $outputFileCounter = 0; - my $fileName = $name.$outputFileCounter.".".$strippedFileExtension; + my $fileName = $name . $outputFileCounter . "." . $strippedFileExtension; $logger->info("will search for existence and increment counter, starting with $fileName"); - while( -e $fileName ){ + while ( -e $fileName ) { $logger->info("$fileName exists, incrementing counter"); $outputFileCounter++; - $fileName = $name.$outputFileCounter.".".$strippedFileExtension; + $fileName = $name . $outputFileCounter . "." . $strippedFileExtension; } $logger->info("$fileName does not exist, and will be the output file"); ${$self}{outputToFile} = $fileName; @@ -153,36 +165,39 @@ sub file_extension_check{ # read the file into the Document body my @lines; - if($fileName ne "-"){ - my $openFilePossible=1; - open(MAINFILE, $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 indendation done for $fileName"); - return 4; - } else { - $logger->fatal("*$fileName exists, but could not open it"); - $logger->fatal("Exiting, no indendation done."); - $self->output_logfile(); - exit(4); + if ( $fileName ne "-" ) { + my $openFilePossible = 1; + open( MAINFILE, $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 indendation done for $fileName"); + return 4; + } + else { + $logger->fatal("*$fileName exists, but could not open it"); + $logger->fatal("Exiting, no indendation done."); + $self->output_logfile(); + exit(4); } } - push(@lines,$_) while(<MAINFILE>); + push( @lines, $_ ) while (<MAINFILE>); close(MAINFILE); - } else { - push(@lines,$_) while (<>) + } + 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); + 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 + # necessary extra storage if # # check switch is active # @@ -190,7 +205,7 @@ sub file_extension_check{ # # $switches{overwriteIfDifferent} # - if ($is_check_switch_active or $switches{overwriteIfDifferent}){ + if ( $is_check_switch_active or $switches{overwriteIfDifferent} ) { ${$self}{originalBody} = ${$self}{body}; } diff --git a/Master/texmf-dist/scripts/latexindent/LatexIndent/GetYamlSettings.pm b/Master/texmf-dist/scripts/latexindent/LatexIndent/GetYamlSettings.pm index b8a9aa0d4e1..24e1291e754 100644 --- a/Master/texmf-dist/scripts/latexindent/LatexIndent/GetYamlSettings.pm +++ b/Master/texmf-dist/scripts/latexindent/LatexIndent/GetYamlSettings.pm @@ -1,4 +1,5 @@ package LatexIndent::GetYamlSettings; + # 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 @@ -18,13 +19,14 @@ use strict; use warnings; use Data::Dumper; use LatexIndent::Switches qw/%switches $is_m_switch_active $is_t_switch_active $is_tt_switch_active/; -use YAML::Tiny; # interpret defaultSettings.yaml and other potential settings files -use File::Basename; # to get the filename and directory path +use YAML::Tiny; # interpret defaultSettings.yaml and other potential settings files +use File::Basename; # to get the filename and directory path use File::HomeDir; use Cwd; use Exporter qw/import/; use LatexIndent::LogFile qw/$logger/; -our @EXPORT_OK = qw/yaml_read_settings yaml_modify_line_breaks_settings yaml_get_indentation_settings_for_this_object yaml_poly_switch_get_every_or_custom_value yaml_get_indentation_information yaml_get_object_attribute_for_indentation_settings yaml_alignment_at_ampersand_settings %mainSettings/; +our @EXPORT_OK + = qw/yaml_read_settings yaml_modify_line_breaks_settings yaml_get_indentation_settings_for_this_object yaml_poly_switch_get_every_or_custom_value yaml_get_indentation_information yaml_get_object_attribute_for_indentation_settings yaml_alignment_at_ampersand_settings %mainSettings/; # Read in defaultSettings.YAML file our $defaultSettings; @@ -36,356 +38,428 @@ our %mainSettings; our %previouslyFoundSettings; # default values for align at ampersand routine -our @alignAtAmpersandInformation = ( {name=>"lookForAlignDelims",yamlname=>"delims",default=>1}, - {name=>"alignDoubleBackSlash",default=>1}, - {name=>"spacesBeforeDoubleBackSlash",default=>1}, - {name=>"multiColumnGrouping",default=>0}, - {name=>"alignRowsWithoutMaxDelims",default=>1}, - {name=>"spacesBeforeAmpersand",default=>1}, - {name=>"spacesAfterAmpersand",default=>1}, - {name=>"justification",default=>"left"}, - {name=>"alignFinalDoubleBackSlash",default=>0}, - {name=>"dontMeasure",default=>0}, - {name=>"delimiterRegEx",default=>"(?<!\\\\)(&)"}, - {name=>"delimiterJustification",default=>"left"}, - {name=>"leadingBlankColumn",default=>-1}, - {name=>"lookForChildCodeBlocks",default=>1}, - ); - -sub yaml_read_settings{ - my $self = shift; - - # read the default settings - $defaultSettings = YAML::Tiny->read( "$FindBin::RealBin/defaultSettings.yaml" ) if ( -e "$FindBin::RealBin/defaultSettings.yaml" ); - - # grab the logger object - $logger->info("*YAML settings read: defaultSettings.yaml"); - $logger->info("Reading defaultSettings.yaml from $FindBin::RealBin/defaultSettings.yaml"); - my $myLibDir = dirname(__FILE__); - - # if latexindent.exe is invoked from TeXLive, then defaultSettings.yaml won't be in - # the same directory as it; we need to navigate to it - if(!$defaultSettings) { - $logger->info("Reading defaultSettings.yaml (2nd attempt) from $FindBin::RealBin/../../texmf-dist/scripts/latexindent/defaultSettings.yaml"); - $logger->info("and then, if necessary, $FindBin::RealBin/LatexIndent/defaultSettings.yaml"); - if ( -e "$FindBin::RealBin/../../texmf-dist/scripts/latexindent/defaultSettings.yaml" ){ - $defaultSettings = YAML::Tiny->read( "$FindBin::RealBin/../../texmf-dist/scripts/latexindent/defaultSettings.yaml"); - } elsif ( -e "$FindBin::RealBin/LatexIndent/defaultSettings.yaml" ) { - $defaultSettings = YAML::Tiny->read( "$FindBin::RealBin/LatexIndent/defaultSettings.yaml"); - } elsif ( -e "$myLibDir/defaultSettings.yaml" ) { -+ $defaultSettings = YAML::Tiny->read( "$myLibDir/defaultSettings.yaml"); - } else { +our @alignAtAmpersandInformation = ( + { name => "lookForAlignDelims", yamlname => "delims", default => 1 }, + { name => "alignDoubleBackSlash", default => 1 }, + { name => "spacesBeforeDoubleBackSlash", default => 1 }, + { name => "multiColumnGrouping", default => 0 }, + { name => "alignRowsWithoutMaxDelims", default => 1 }, + { name => "spacesBeforeAmpersand", default => 1 }, + { name => "spacesAfterAmpersand", default => 1 }, + { name => "justification", default => "left" }, + { name => "alignFinalDoubleBackSlash", default => 0 }, + { name => "dontMeasure", default => 0 }, + { name => "delimiterRegEx", default => "(?<!\\\\)(&)" }, + { name => "delimiterJustification", default => "left" }, + { name => "leadingBlankColumn", default => -1 }, + { name => "lookForChildCodeBlocks", default => 1 }, +); + +sub yaml_read_settings { + my $self = shift; + + # read the default settings + $defaultSettings = YAML::Tiny->read("$FindBin::RealBin/defaultSettings.yaml") + if ( -e "$FindBin::RealBin/defaultSettings.yaml" ); + + # grab the logger object + $logger->info("*YAML settings read: defaultSettings.yaml"); + $logger->info("Reading defaultSettings.yaml from $FindBin::RealBin/defaultSettings.yaml"); + my $myLibDir = dirname(__FILE__); + + # if latexindent.exe is invoked from TeXLive, then defaultSettings.yaml won't be in + # the same directory as it; we need to navigate to it + if ( !$defaultSettings ) { + $logger->info( + "Reading defaultSettings.yaml (2nd attempt) from $FindBin::RealBin/../../texmf-dist/scripts/latexindent/defaultSettings.yaml" + ); + $logger->info("and then, if necessary, $FindBin::RealBin/LatexIndent/defaultSettings.yaml"); + if ( -e "$FindBin::RealBin/../../texmf-dist/scripts/latexindent/defaultSettings.yaml" ) { + $defaultSettings + = YAML::Tiny->read("$FindBin::RealBin/../../texmf-dist/scripts/latexindent/defaultSettings.yaml"); + } + elsif ( -e "$FindBin::RealBin/LatexIndent/defaultSettings.yaml" ) { + $defaultSettings = YAML::Tiny->read("$FindBin::RealBin/LatexIndent/defaultSettings.yaml"); + } + elsif ( -e "$myLibDir/defaultSettings.yaml" ) { + +$defaultSettings = YAML::Tiny->read("$myLibDir/defaultSettings.yaml"); + } + else { + $logger->fatal("*Could not open defaultSettings.yaml"); + $self->output_logfile(); + exit(2); + } + } + + # need to exit if we can't get defaultSettings.yaml + if ( !$defaultSettings ) { $logger->fatal("*Could not open defaultSettings.yaml"); $self->output_logfile(); exit(2); } - } - - # need to exit if we can't get defaultSettings.yaml - if(!$defaultSettings){ - $logger->fatal("*Could not open defaultSettings.yaml"); - $self->output_logfile(); - exit(2); - } - - # master yaml settings is a hash, global to this module - our %mainSettings = %{$defaultSettings->[0]}; - - &yaml_update_dumper_settings(); - - # scalar to read user settings - my $userSettings; - - # array to store the paths to user settings - my @absPaths; - - # we'll need the home directory a lot in what follows - my $homeDir = File::HomeDir->my_home; - $logger->info("*YAML settings read: indentconfig.yaml or .indentconfig.yaml") unless $switches{onlyDefault}; - - # get information about user settings- first check if indentconfig.yaml exists - my $indentconfig = "$homeDir/indentconfig.yaml"; - - # if indentconfig.yaml doesn't exist, check for the hidden file, .indentconfig.yaml - $indentconfig = "$homeDir/.indentconfig.yaml" if(! -e $indentconfig); - - # messages for indentconfig.yaml and/or .indentconfig.yaml - if ( -e $indentconfig and !$switches{onlyDefault}) { + + # master yaml settings is a hash, global to this module + our %mainSettings = %{ $defaultSettings->[0] }; + + &yaml_update_dumper_settings(); + + # scalar to read user settings + my $userSettings; + + # array to store the paths to user settings + my @absPaths; + + # we'll need the home directory a lot in what follows + my $homeDir = File::HomeDir->my_home; + $logger->info("*YAML settings read: indentconfig.yaml or .indentconfig.yaml") unless $switches{onlyDefault}; + + # get information about user settings- first check if indentconfig.yaml exists + my $indentconfig = "$homeDir/indentconfig.yaml"; + + # if indentconfig.yaml doesn't exist, check for the hidden file, .indentconfig.yaml + $indentconfig = "$homeDir/.indentconfig.yaml" if ( !-e $indentconfig ); + + # messages for indentconfig.yaml and/or .indentconfig.yaml + if ( -e $indentconfig and !$switches{onlyDefault} ) { + # read the absolute paths from indentconfig.yaml - $userSettings = YAML::Tiny->read( "$indentconfig" ); + $userSettings = YAML::Tiny->read("$indentconfig"); # update the absolute paths - if($userSettings and (ref($userSettings->[0]) eq 'HASH') and $userSettings->[0]->{paths}){ + if ( $userSettings and ( ref( $userSettings->[0] ) eq 'HASH' ) and $userSettings->[0]->{paths} ) { $logger->info("Reading path information from $indentconfig"); + # if both indentconfig.yaml and .indentconfig.yaml exist - if ( -e File::HomeDir->my_home . "/indentconfig.yaml" and -e File::HomeDir->my_home . "/.indentconfig.yaml") { - $logger->info("$homeDir/.indentconfig.yaml has been found, but $indentconfig takes priority"); - } elsif ( -e File::HomeDir->my_home . "/indentconfig.yaml" ) { - $logger->info("(Alternatively $homeDir/.indentconfig.yaml can be used)"); - } elsif ( -e File::HomeDir->my_home . "/.indentconfig.yaml" ) { - $logger->info("(Alternatively $homeDir/indentconfig.yaml can be used)"); + if ( -e File::HomeDir->my_home . "/indentconfig.yaml" + and -e File::HomeDir->my_home . "/.indentconfig.yaml" ) + { + $logger->info("$homeDir/.indentconfig.yaml has been found, but $indentconfig takes priority"); + } + elsif ( -e File::HomeDir->my_home . "/indentconfig.yaml" ) { + $logger->info("(Alternatively $homeDir/.indentconfig.yaml can be used)"); } - + elsif ( -e File::HomeDir->my_home . "/.indentconfig.yaml" ) { + $logger->info("(Alternatively $homeDir/indentconfig.yaml can be used)"); + } + # output the contents of indentconfig to the log file - $logger->info(Dump \%{$userSettings->[0]}); - + $logger->info( Dump \%{ $userSettings->[0] } ); + # change the encoding of the paths according to the field `encoding` - if($userSettings and (ref($userSettings->[0]) eq 'HASH') and $userSettings->[0]->{encoding}){ + if ( $userSettings and ( ref( $userSettings->[0] ) eq 'HASH' ) and $userSettings->[0]->{encoding} ) { use Encode; - my $encoding = $userSettings->[0]->{encoding}; + my $encoding = $userSettings->[0]->{encoding}; my $encodingObject = find_encoding($encoding); + # Check if the encoding is valid. - if (ref($encodingObject)) - { + if ( ref($encodingObject) ) { $logger->info("*Encoding of the paths is $encoding"); - foreach (@{$userSettings->[0]->{paths}}) - { + foreach ( @{ $userSettings->[0]->{paths} } ) { my $temp = $encodingObject->encode("$_"); $logger->info("Transform file encoding: $_ -> $temp"); - push(@absPaths,$temp); + push( @absPaths, $temp ); } } - else - { + else { $logger->warn("*encoding \"$encoding\" not found"); $logger->warn("Ignore this setting and will take the default encoding."); - @absPaths = @{$userSettings->[0]->{paths}}; + @absPaths = @{ $userSettings->[0]->{paths} }; } } - else # No such setting, and will take the default + else # No such setting, and will take the default { # $logger->info("*Encoding of the paths takes the default."); - @absPaths = @{$userSettings->[0]->{paths}}; + @absPaths = @{ $userSettings->[0]->{paths} }; } - } else { - $logger->warn("*The paths field cannot be read from $indentconfig; this means it is either empty or contains invalid YAML"); - $logger->warn("See https://latexindentpl.readthedocs.io/en/latest/sec-indent-config-and-settings.html for an example"); } - } else { - if($switches{onlyDefault}) { - $logger->info("*-d switch active: only default settings requested"); - $logger->info("not reading USER settings from $indentconfig") if (-e $indentconfig); - $logger->info("Ignoring the -l switch: $switches{readLocalSettings} (you used the -d switch)") if($switches{readLocalSettings}); - $logger->info("Ignoring the -y switch: $switches{yaml} (you used the -d switch)") if($switches{yaml}); - $switches{readLocalSettings}=0; - $switches{yaml}=0; - } else { - # give the user instructions on where to put indentconfig.yaml or .indentconfig.yaml - $logger->info("Home directory is $homeDir (didn't find either indentconfig.yaml or .indentconfig.yaml)\nTo specify user settings you would put indentconfig.yaml here: $homeDir/indentconfig.yaml\nAlternatively, you can use the hidden file .indentconfig.yaml as: $homeDir/.indentconfig.yaml"); - } - } - - # default value of readLocalSettings - # - # latexindent -l myfile.tex - # - # means that we wish to use localSettings.yaml - if(defined($switches{readLocalSettings}) and ($switches{readLocalSettings} eq '')){ - $logger->info('*-l switch used without filename, will search for the following files in turn:'); - $logger->info('localSettings.yaml,latexindent.yaml,.localSettings.yaml,.latexindent.yaml'); - $switches{readLocalSettings} = 'localSettings.yaml,latexindent.yaml,.localSettings.yaml,.latexindent.yaml'; - } - - # local settings can be called with a + symbol, for example - # -l=+myfile.yaml - # -l "+ myfile.yaml" - # -l=myfile.yaml+ - # which translates to, respectively - # -l=localSettings.yaml,myfile.yaml - # -l=myfile.yaml,localSettings.yaml - # Note: the following is *not allowed*: - # -l+myfile.yaml - # and - # -l + myfile.yaml - # will *only* load localSettings.yaml, and myfile.yaml will be ignored - my @localSettings; - - $logger->info("*YAML settings read: -l switch") if $switches{readLocalSettings}; - - # remove leading, trailing, and intermediate space - $switches{readLocalSettings} =~ s/^\h*//g; - $switches{readLocalSettings} =~ s/\h*$//g; - $switches{readLocalSettings} =~ s/\h*,\h*/,/g; - if($switches{readLocalSettings} =~ m/\+/){ - $logger->info("+ found in call for -l switch: will add localSettings.yaml,latexindent.yaml,.localSettings.yaml,.latexindent.yaml"); + else { + $logger->warn( + "*The paths field cannot be read from $indentconfig; this means it is either empty or contains invalid YAML" + ); + $logger->warn( + "See https://latexindentpl.readthedocs.io/en/latest/sec-indent-config-and-settings.html for an example" + ); + } + } + else { + if ( $switches{onlyDefault} ) { + $logger->info("*-d switch active: only default settings requested"); + $logger->info("not reading USER settings from $indentconfig") if ( -e $indentconfig ); + $logger->info("Ignoring the -l switch: $switches{readLocalSettings} (you used the -d switch)") + if ( $switches{readLocalSettings} ); + $logger->info("Ignoring the -y switch: $switches{yaml} (you used the -d switch)") if ( $switches{yaml} ); + $switches{readLocalSettings} = 0; + $switches{yaml} = 0; + } + else { + # give the user instructions on where to put indentconfig.yaml or .indentconfig.yaml + $logger->info( + "Home directory is $homeDir (didn't find either indentconfig.yaml or .indentconfig.yaml)\nTo specify user settings you would put indentconfig.yaml here: $homeDir/indentconfig.yaml\nAlternatively, you can use the hidden file .indentconfig.yaml as: $homeDir/.indentconfig.yaml" + ); + } + } + + # default value of readLocalSettings + # + # latexindent -l myfile.tex + # + # means that we wish to use localSettings.yaml + if ( defined( $switches{readLocalSettings} ) and ( $switches{readLocalSettings} eq '' ) ) { + $logger->info('*-l switch used without filename, will search for the following files in turn:'); + $logger->info('localSettings.yaml,latexindent.yaml,.localSettings.yaml,.latexindent.yaml'); + $switches{readLocalSettings} = 'localSettings.yaml,latexindent.yaml,.localSettings.yaml,.latexindent.yaml'; + } + + # local settings can be called with a + symbol, for example + # -l=+myfile.yaml + # -l "+ myfile.yaml" + # -l=myfile.yaml+ + # which translates to, respectively + # -l=localSettings.yaml,myfile.yaml + # -l=myfile.yaml,localSettings.yaml + # Note: the following is *not allowed*: + # -l+myfile.yaml + # and + # -l + myfile.yaml + # will *only* load localSettings.yaml, and myfile.yaml will be ignored + my @localSettings; + + $logger->info("*YAML settings read: -l switch") if $switches{readLocalSettings}; + + # remove leading, trailing, and intermediate space + $switches{readLocalSettings} =~ s/^\h*//g; + $switches{readLocalSettings} =~ s/\h*$//g; + $switches{readLocalSettings} =~ s/\h*,\h*/,/g; + if ( $switches{readLocalSettings} =~ m/\+/ ) { + $logger->info( + "+ found in call for -l switch: will add localSettings.yaml,latexindent.yaml,.localSettings.yaml,.latexindent.yaml" + ); # + can be either at the beginning or the end, which determines if where the comma should go - my $commaAtBeginning = ($switches{readLocalSettings} =~ m/^\h*\+/ ? q() : ","); - my $commaAtEnd = ($switches{readLocalSettings} =~ m/^\h*\+/ ? "," : q()); + my $commaAtBeginning = ( $switches{readLocalSettings} =~ m/^\h*\+/ ? q() : "," ); + my $commaAtEnd = ( $switches{readLocalSettings} =~ m/^\h*\+/ ? "," : q() ); $switches{readLocalSettings} =~ s/\h*\+\h*/$commaAtBeginning ."localSettings.yaml,latexindent.yaml,.localSettings.yaml,.latexindent.yaml" - .$commaAtEnd/ex; + .$commaAtEnd/ex; $logger->info("New value of -l switch: $switches{readLocalSettings}"); - } + } - # local settings can be separated by , - # e.g - # -l = myyaml1.yaml,myyaml2.yaml - # and in which case, we need to read them all - if($switches{readLocalSettings} =~ m/,/){ + # local settings can be separated by , + # e.g + # -l = myyaml1.yaml,myyaml2.yaml + # and in which case, we need to read them all + if ( $switches{readLocalSettings} =~ m/,/ ) { $logger->info("Multiple localSettings found, separated by commas:"); - @localSettings = split(/,/,$switches{readLocalSettings}); - $logger->info(join(', ',@localSettings)); - } else { - push(@localSettings,$switches{readLocalSettings}) if($switches{readLocalSettings}); - } - - my $workingFileLocation = dirname (${$self}{fileName}); - # add local settings to the paths, if appropriate - foreach (@localSettings) { - # check for an extension (.yaml) - my ($name, $dir , $ext) = fileparse($_, "yaml"); - - # if no extension is found, append the current localSetting with .yaml - $_ = $_.($_=~m/\.\z/ ? q() : ".")."yaml" if(!$ext); - - # if the -l switch is called on its own, or else with + - # and latexindent.pl is called from a different directory, then - # we need to account for this - if($_ eq "localSettings.yaml" ){ - # check for existence in the directory of the file. - if ( (-e $workingFileLocation."/".$_) ) { - $_ = $workingFileLocation."/".$_; - # otherwise we fallback to the current directory - } elsif( (-e cwd()."/".$_) ){ - $_ = cwd()."/".$_; - } + @localSettings = split( /,/, $switches{readLocalSettings} ); + $logger->info( join( ', ', @localSettings ) ); + } + else { + push( @localSettings, $switches{readLocalSettings} ) if ( $switches{readLocalSettings} ); } - # check for existence and non-emptiness - if ( (-e $_) and !(-z $_)) { - $logger->info("Adding $_ to YAML read paths"); - push(@absPaths,"$_"); - } elsif ( !(-e $_) ) { - if ( ($_ =~ m/localSettings|latexindent/s - and !(-e 'localSettings.yaml') - and !(-e '.localSettings.yaml') - and !(-e 'latexindent.yaml') - and !(-e '.latexindent.yaml')) - or $_ !~ m/localSettings|latexindent/s - ){ + my $workingFileLocation = dirname( ${$self}{fileName} ); + + # add local settings to the paths, if appropriate + foreach (@localSettings) { + + # check for an extension (.yaml) + my ( $name, $dir, $ext ) = fileparse( $_, "yaml" ); + + # if no extension is found, append the current localSetting with .yaml + $_ = $_ . ( $_ =~ m/\.\z/ ? q() : "." ) . "yaml" if ( !$ext ); + + # if the -l switch is called on its own, or else with + + # and latexindent.pl is called from a different directory, then + # we need to account for this + if ( $_ eq "localSettings.yaml" ) { + + # check for existence in the directory of the file. + if ( ( -e $workingFileLocation . "/" . $_ ) ) { + $_ = $workingFileLocation . "/" . $_; + + # otherwise we fallback to the current directory + } + elsif ( ( -e cwd() . "/" . $_ ) ) { + $_ = cwd() . "/" . $_; + } + } + + # check for existence and non-emptiness + if ( ( -e $_ ) and !( -z $_ ) ) { + $logger->info("Adding $_ to YAML read paths"); + push( @absPaths, "$_" ); + } + elsif ( !( -e $_ ) ) { + if (( $_ =~ m/localSettings|latexindent/s + and !( -e 'localSettings.yaml' ) + and !( -e '.localSettings.yaml' ) + and !( -e 'latexindent.yaml' ) + and !( -e '.latexindent.yaml' ) + ) + or $_ !~ m/localSettings|latexindent/s + ) + { $logger->warn("*yaml file not found: $_ not found. Proceeding without it."); + } } } - } - - # heading for the log file - $logger->info("*YAML settings, reading from the following files:") if @absPaths; - - # read in the settings from each file - foreach my $settings (@absPaths) { - # check that the settings file exists and that it isn't empty - if (-e $settings and !(-z $settings)) { - $logger->info("Reading USER settings from $settings"); - $userSettings = YAML::Tiny->read( "$settings" ); - - # if we can read userSettings - if($userSettings) { - # update the MASTER setttings to include updates from the userSettings - while(my($firstLevelKey, $firstLevelValue) = each %{$userSettings->[0]}) { - # the update approach is slightly different for hashes vs scalars/arrays - if (ref($firstLevelValue) eq "HASH") { - while(my ($secondLevelKey,$secondLevelValue) = each %{$userSettings->[0]{$firstLevelKey}}) { - if (ref $secondLevelValue eq "HASH"){ - # if mainSettings already contains a *scalar* value in secondLevelKey - # then we need to delete it (test-cases/headings-first.tex with indentRules1.yaml first demonstrated this) - if(defined $mainSettings{$firstLevelKey}{$secondLevelKey} - and ref $mainSettings{$firstLevelKey}{$secondLevelKey} ne "HASH"){ - $logger->trace("*mainSettings{$firstLevelKey}{$secondLevelKey} currently contains a *scalar* value, but it needs to be updated with a hash (see $settings); deleting the scalar") if($is_t_switch_active); - delete $mainSettings{$firstLevelKey}{$secondLevelKey} ; + + # heading for the log file + $logger->info("*YAML settings, reading from the following files:") if @absPaths; + + # read in the settings from each file + foreach my $settings (@absPaths) { + + # check that the settings file exists and that it isn't empty + if ( -e $settings and !( -z $settings ) ) { + $logger->info("Reading USER settings from $settings"); + $userSettings = YAML::Tiny->read("$settings"); + + # if we can read userSettings + if ($userSettings) { + + # update the MASTER setttings to include updates from the userSettings + while ( my ( $firstLevelKey, $firstLevelValue ) = each %{ $userSettings->[0] } ) { + + # the update approach is slightly different for hashes vs scalars/arrays + if ( ref($firstLevelValue) eq "HASH" ) { + while ( my ( $secondLevelKey, $secondLevelValue ) + = each %{ $userSettings->[0]{$firstLevelKey} } ) + { + if ( ref $secondLevelValue eq "HASH" ) { + + # if mainSettings already contains a *scalar* value in secondLevelKey + # then we need to delete it (test-cases/headings-first.tex with indentRules1.yaml first demonstrated this) + if ( defined $mainSettings{$firstLevelKey}{$secondLevelKey} + and ref $mainSettings{$firstLevelKey}{$secondLevelKey} ne "HASH" ) + { + $logger->trace( + "*mainSettings{$firstLevelKey}{$secondLevelKey} currently contains a *scalar* value, but it needs to be updated with a hash (see $settings); deleting the scalar" + ) if ($is_t_switch_active); + delete $mainSettings{$firstLevelKey}{$secondLevelKey}; } - while(my ($thirdLevelKey,$thirdLevelValue) = each %{$secondLevelValue}) { - if (ref $thirdLevelValue eq "HASH"){ + while ( my ( $thirdLevelKey, $thirdLevelValue ) = each %{$secondLevelValue} ) { + if ( ref $thirdLevelValue eq "HASH" ) { + # similarly for third level - if (defined $mainSettings{$firstLevelKey}{$secondLevelKey}{$thirdLevelKey} - and ref $mainSettings{$firstLevelKey}{$secondLevelKey}{$thirdLevelKey} ne "HASH"){ - $logger->trace("*mainSettings{$firstLevelKey}{$secondLevelKey}{$thirdLevelKey} currently contains a *scalar* value, but it needs to be updated with a hash (see $settings); deleting the scalar") if($is_t_switch_active); - delete $mainSettings{$firstLevelKey}{$secondLevelKey}{$thirdLevelKey} ; + if ( defined $mainSettings{$firstLevelKey}{$secondLevelKey}{$thirdLevelKey} + and ref $mainSettings{$firstLevelKey}{$secondLevelKey}{$thirdLevelKey} ne + "HASH" ) + { + $logger->trace( + "*mainSettings{$firstLevelKey}{$secondLevelKey}{$thirdLevelKey} currently contains a *scalar* value, but it needs to be updated with a hash (see $settings); deleting the scalar" + ) if ($is_t_switch_active); + delete $mainSettings{$firstLevelKey}{$secondLevelKey}{$thirdLevelKey}; } - while(my ($fourthLevelKey,$fourthLevelValue) = each %{$thirdLevelValue}) { - $mainSettings{$firstLevelKey}{$secondLevelKey}{$thirdLevelKey}{$fourthLevelKey} = $fourthLevelValue; + while ( my ( $fourthLevelKey, $fourthLevelValue ) = each %{$thirdLevelValue} ) { + $mainSettings{$firstLevelKey}{$secondLevelKey}{$thirdLevelKey} + {$fourthLevelKey} = $fourthLevelValue; } - } else { - $mainSettings{$firstLevelKey}{$secondLevelKey}{$thirdLevelKey} = $thirdLevelValue; + } + else { + $mainSettings{$firstLevelKey}{$secondLevelKey}{$thirdLevelKey} + = $thirdLevelValue; } } - } else { - # settings such as commandCodeBlocks can have arrays, which may wish + } + else { + # settings such as commandCodeBlocks can have arrays, which may wish # to be amalgamated, rather than overwritten - if(ref($secondLevelValue) eq "ARRAY" - and - ${${$mainSettings{$firstLevelKey}{$secondLevelKey}}[0]}{amalgamate} - and - !(ref(${$secondLevelValue}[0]) eq "HASH" and defined ${$secondLevelValue}[0]{amalgamate} and !${$secondLevelValue}[0]{amalgamate}) - ){ - $logger->trace("*$firstLevelKey -> $secondLevelKey, amalgamate: 1") if($is_t_switch_active); - foreach (@{$secondLevelValue}){ - $logger->trace("$_") if($is_t_switch_active); - push (@{$mainSettings{$firstLevelKey}{$secondLevelKey}},$_) unless(ref($_) eq "HASH"); + if ( ref($secondLevelValue) eq "ARRAY" + and ${ ${ $mainSettings{$firstLevelKey}{$secondLevelKey} }[0] }{amalgamate} + and !( + ref( ${$secondLevelValue}[0] ) eq "HASH" + and defined ${$secondLevelValue}[0]{amalgamate} + and !${$secondLevelValue}[0]{amalgamate} + ) + ) + { + $logger->trace("*$firstLevelKey -> $secondLevelKey, amalgamate: 1") + if ($is_t_switch_active); + foreach ( @{$secondLevelValue} ) { + $logger->trace("$_") if ($is_t_switch_active); + push( @{ $mainSettings{$firstLevelKey}{$secondLevelKey} }, $_ ) + unless ( ref($_) eq "HASH" ); } - # remove duplicated entries, https://stackoverflow.com/questions/7651/how-do-i-remove-duplicate-items-from-an-array-in-perl +# remove duplicated entries, https://stackoverflow.com/questions/7651/how-do-i-remove-duplicate-items-from-an-array-in-perl my %seen = (); - my @unique = grep { ! $seen{ $_ }++ } @{$mainSettings{$firstLevelKey}{$secondLevelKey}}; - @{$mainSettings{$firstLevelKey}{$secondLevelKey}} = @unique; - - $logger->trace("*master settings for $firstLevelKey -> $secondLevelKey now look like:") if $is_t_switch_active; - foreach (@{$mainSettings{$firstLevelKey}{$secondLevelKey}}){ - $logger->trace("$_") if($is_t_switch_active); + my @unique + = grep { !$seen{$_}++ } @{ $mainSettings{$firstLevelKey}{$secondLevelKey} }; + @{ $mainSettings{$firstLevelKey}{$secondLevelKey} } = @unique; + + $logger->trace( + "*master settings for $firstLevelKey -> $secondLevelKey now look like:") + if $is_t_switch_active; + foreach ( @{ $mainSettings{$firstLevelKey}{$secondLevelKey} } ) { + $logger->trace("$_") if ($is_t_switch_active); } - } else { + } + else { $mainSettings{$firstLevelKey}{$secondLevelKey} = $secondLevelValue; } } - } - } elsif (ref($firstLevelValue) eq "ARRAY") { - # update amalgamate in master settings - if(ref(${$firstLevelValue}[0]) eq "HASH" and defined ${$firstLevelValue}[0]{amalgamate}){ - ${$mainSettings{$firstLevelKey}[0]}{amalgamate} = ${$firstLevelValue}[0]{amalgamate}; - shift @{$firstLevelValue} if ${$mainSettings{$firstLevelKey}[0]}{amalgamate}; - } + } + } + elsif ( ref($firstLevelValue) eq "ARRAY" ) { - # if amalgamate is set to 1, then append - if(${$mainSettings{$firstLevelKey}[0]}{amalgamate}){ - # loop through the other settings - foreach (@{$firstLevelValue}){ - push (@{$mainSettings{$firstLevelKey}},$_); - } - } else { - # otherwise overwrite - $mainSettings{$firstLevelKey} = $firstLevelValue; + # update amalgamate in master settings + if ( ref( ${$firstLevelValue}[0] ) eq "HASH" and defined ${$firstLevelValue}[0]{amalgamate} ) { + ${ $mainSettings{$firstLevelKey}[0] }{amalgamate} = ${$firstLevelValue}[0]{amalgamate}; + shift @{$firstLevelValue} if ${ $mainSettings{$firstLevelKey}[0] }{amalgamate}; + } + + # if amalgamate is set to 1, then append + if ( ${ $mainSettings{$firstLevelKey}[0] }{amalgamate} ) { + + # loop through the other settings + foreach ( @{$firstLevelValue} ) { + push( @{ $mainSettings{$firstLevelKey} }, $_ ); } - } else { + } + else { + # otherwise overwrite $mainSettings{$firstLevelKey} = $firstLevelValue; - } - } - - # output settings to $logfile - if($mainSettings{logFilePreferences}{showEveryYamlRead}){ - $logger->info(Dump \%{$userSettings->[0]}); - } else { - $logger->info("Not showing settings in the log file (see showEveryYamlRead and showAmalgamatedSettings)."); - } - } else { - # otherwise print a warning that we can not read userSettings.yaml - $logger->warn("*$settings contains invalid yaml format- not reading from it"); - } - } else { - # otherwise keep going, but put a warning in the log file - $logger->warn("*$homeDir/indentconfig.yaml"); - if (-z $settings) { - $logger->info("specifies $settings but this file is EMPTY -- not reading from it"); - } else { - $logger->info("specifies $settings but this file does not exist - unable to read settings from this file"); + } + } + else { + $mainSettings{$firstLevelKey} = $firstLevelValue; + } + } + + # output settings to $logfile + if ( $mainSettings{logFilePreferences}{showEveryYamlRead} ) { + $logger->info( Dump \%{ $userSettings->[0] } ); + } + else { + $logger->info( + "Not showing settings in the log file (see showEveryYamlRead and showAmalgamatedSettings)."); + } + } + else { + # otherwise print a warning that we can not read userSettings.yaml + $logger->warn("*$settings contains invalid yaml format- not reading from it"); + } + } + else { + # otherwise keep going, but put a warning in the log file + $logger->warn("*$homeDir/indentconfig.yaml"); + if ( -z $settings ) { + $logger->info("specifies $settings but this file is EMPTY -- not reading from it"); + } + else { + $logger->info( + "specifies $settings but this file does not exist - unable to read settings from this file"); + } } - } - &yaml_update_dumper_settings(); + &yaml_update_dumper_settings(); + + } - } + # read settings from -y|--yaml switch + if ( $switches{yaml} ) { - # read settings from -y|--yaml switch - if($switches{yaml}){ # report to log file $logger->info("*YAML settings read: -y switch"); @@ -395,15 +469,16 @@ sub yaml_read_settings{ # store settings, possibly multiple ones split by commas my @yamlSettings; - if($switches{yaml} =~ m/(?<!\\),/){ - @yamlSettings = split(/(?<!\\),/,$switches{yaml}); - } else { - push(@yamlSettings,$switches{yaml}); + if ( $switches{yaml} =~ m/(?<!\\),/ ) { + @yamlSettings = split( /(?<!\\),/, $switches{yaml} ); + } + else { + push( @yamlSettings, $switches{yaml} ); } - foreach (@yamlSettings){ - $logger->info("YAML setting: ".$_); - } + foreach (@yamlSettings) { + $logger->info( "YAML setting: " . $_ ); + } # it is possible to specify, for example, # @@ -417,35 +492,36 @@ sub yaml_read_settings{ # indentAfterThisHeading:1 # level:1 # - # so we need to loop through the comma separated list and search + # so we need to loop through the comma separated list and search # for semi-colons - my $settingsCounter=0; + my $settingsCounter = 0; my @originalYamlSettings = @yamlSettings; - foreach(@originalYamlSettings){ + foreach (@originalYamlSettings) { + # increment the counter $settingsCounter++; - # need to be careful in splitting at ';' - # - # motivation as detailed in https://github.com/cmhughes/latexindent.pl/issues/243 - # - # latexindent.pl -m -y='modifyLineBreaks:oneSentencePerLine:manipulateSentences: 1, - # modifyLineBreaks:oneSentencePerLine:sentencesBeginWith:a-z: 1, - # fineTuning:modifyLineBreaks:betterFullStop: "(?:\.|;|:(?![a-z]))|(?:(?<!(?:(?:e\.g)|(?:i\.e)|(?:etc))))\.(?!(?:[a-z]|[A-Z]|\-|~|\,|[0-9]))"' myfile.tex - # - # in particular, the fineTuning part needs care in treating the argument between the quotes - +# need to be careful in splitting at ';' +# +# motivation as detailed in https://github.com/cmhughes/latexindent.pl/issues/243 +# +# latexindent.pl -m -y='modifyLineBreaks:oneSentencePerLine:manipulateSentences: 1, +# modifyLineBreaks:oneSentencePerLine:sentencesBeginWith:a-z: 1, +# fineTuning:modifyLineBreaks:betterFullStop: "(?:\.|;|:(?![a-z]))|(?:(?<!(?:(?:e\.g)|(?:i\.e)|(?:etc))))\.(?!(?:[a-z]|[A-Z]|\-|~|\,|[0-9]))"' myfile.tex +# +# in particular, the fineTuning part needs care in treating the argument between the quotes + # check for a match of the ; - if($_ !~ m/(?<!(?:\\))"/ and $_ =~ m/(?<!\\);/){ - my (@subfield) = split(/(?<!\\);/,$_); + if ( $_ !~ m/(?<!(?:\\))"/ and $_ =~ m/(?<!\\);/ ) { + my (@subfield) = split( /(?<!\\);/, $_ ); # the content up to the first ; is called the 'root' my $root = shift @subfield; # split the root at : - my (@keysValues) = split(/:/,$root); + my (@keysValues) = split( /:/, $root ); - # get rid of the last *two* elements, which will be + # get rid of the last *two* elements, which will be # key: value # for example, in # -y=indentAfterHeadings:paragraph:indentAfterThisHeading:1;level:1 @@ -456,7 +532,7 @@ sub yaml_read_settings{ # indentAfterThisHeading # so that we are in a position to concatenate # indentAfterHeadings:paragraph - # with + # with # level:1 # to form # indentAfterHeadings:paragraph:level:1 @@ -467,62 +543,63 @@ sub yaml_read_settings{ # -y=indentAfterHeadings:paragraph:indentAfterThisHeading:1;level:1 # needs to be changed to # -y=indentAfterHeadings:paragraph:indentAfterThisHeading:1 - # the + # the # indentAfterHeadings:paragraph:level:1 # will be added in the next part - $yamlSettings[$settingsCounter-1] = $root; + $yamlSettings[ $settingsCounter - 1 ] = $root; # reform the root - $root = join(":",@keysValues); + $root = join( ":", @keysValues ); $logger->trace("*Sub-field detected (; present) and the root is: $root") if $is_t_switch_active; # now we need to attach the $root back together with any subfields - foreach(@subfield){ - # splice the new field into @yamlSettings (reference: https://perlmaven.com/splice-to-slice-and-dice-arrays-in-perl) - splice @yamlSettings,$settingsCounter,0,$root.":".$_; - - # increment the counter - $settingsCounter++; + foreach (@subfield) { + + # splice the new field into @yamlSettings (reference: https://perlmaven.com/splice-to-slice-and-dice-arrays-in-perl) + splice @yamlSettings, $settingsCounter, 0, $root . ":" . $_; + + # increment the counter + $settingsCounter++; } - $logger->info("-y switch value interpreted as: ".join(',',@yamlSettings)); + $logger->info( "-y switch value interpreted as: " . join( ',', @yamlSettings ) ); } } # loop through each of the settings specified in the -y switch - foreach(@yamlSettings){ + foreach (@yamlSettings) { my @keysValues; - # as above, need to be careful in splitting at ':' - # - # motivation as detailed in https://github.com/cmhughes/latexindent.pl/issues/243 - # - # latexindent.pl -m -y='modifyLineBreaks:oneSentencePerLine:manipulateSentences: 1, - # modifyLineBreaks:oneSentencePerLine:sentencesBeginWith:a-z: 1, - # fineTuning:modifyLineBreaks:betterFullStop: "(?:\.|;|:(?![a-z]))|(?:(?<!(?:(?:e\.g)|(?:i\.e)|(?:etc))))\.(?!(?:[a-z]|[A-Z]|\-|~|\,|[0-9]))"' myfile.tex - # - # in particular, the fineTuning part needs care in treating the argument between the quotes - - if ($_ =~ m/(?<!(?:\\))"/){ - my (@splitAtQuote) = split(/(?<!(?:\\))"/,$_); +# as above, need to be careful in splitting at ':' +# +# motivation as detailed in https://github.com/cmhughes/latexindent.pl/issues/243 +# +# latexindent.pl -m -y='modifyLineBreaks:oneSentencePerLine:manipulateSentences: 1, +# modifyLineBreaks:oneSentencePerLine:sentencesBeginWith:a-z: 1, +# fineTuning:modifyLineBreaks:betterFullStop: "(?:\.|;|:(?![a-z]))|(?:(?<!(?:(?:e\.g)|(?:i\.e)|(?:etc))))\.(?!(?:[a-z]|[A-Z]|\-|~|\,|[0-9]))"' myfile.tex +# +# in particular, the fineTuning part needs care in treating the argument between the quotes + + if ( $_ =~ m/(?<!(?:\\))"/ ) { + my (@splitAtQuote) = split( /(?<!(?:\\))"/, $_ ); $logger->info("quote found in -y switch"); - $logger->info("key: ".$splitAtQuote[0]); + $logger->info( "key: " . $splitAtQuote[0] ); # definition check $splitAtQuote[1] = '' if not defined $splitAtQuote[1]; # then log the value - $logger->info("value: ".$splitAtQuote[1]); + $logger->info( "value: " . $splitAtQuote[1] ); # split at : - (@keysValues) = split(/(?<!(?:\\|\[)):(?!\])/,$splitAtQuote[0]); + (@keysValues) = split( /(?<!(?:\\|\[)):(?!\])/, $splitAtQuote[0] ); - $splitAtQuote[1] = '"'.$splitAtQuote[1].'"'; - push(@keysValues,$splitAtQuote[1]); - } + $splitAtQuote[1] = '"' . $splitAtQuote[1] . '"'; + push( @keysValues, $splitAtQuote[1] ); + } else { # split each value at semi-colon - (@keysValues) = split(/(?<!(?:\\|\[)):(?!\])/,$_); + (@keysValues) = split( /(?<!(?:\\|\[)):(?!\])/, $_ ); } # $value will always be the last element @@ -533,22 +610,28 @@ sub yaml_read_settings{ $value =~ s/\\:/:/; # strings need special treatment - if($value =~ m/^"(.*)"$/){ + if ( $value =~ m/^"(.*)"$/ ) { + # double-quoted string # translate: '\t', '\n', '\"', '\\' my $raw_value = $value; $value = $1; + # only translate string starts with an odd number of escape characters '\' $value =~ s/(?<!\\)((\\\\)*)\\t/$1\t/g; $value =~ s/(?<!\\)((\\\\)*)\\n/$1\n/g; $value =~ s/(?<!\\)((\\\\)*)\\"/$1"/g; + # translate '\\' in double-quoted strings, but not in single-quoted strings $value =~ s/\\\\/\\/g; $logger->info("double-quoted string found in -y switch: $raw_value, substitute to $value"); - } elsif($value =~ m/^'(.*)'$/){ + } + elsif ( $value =~ m/^'(.*)'$/ ) { + # single-quoted string my $raw_value = $value; $value = $1; + # special treatment for tabs and newlines # translate: '\t', '\n' # only translate string starts with an odd number of escape characters '\' @@ -557,62 +640,73 @@ sub yaml_read_settings{ $logger->info("single-quoted string found in -y switch: $raw_value, substitute to $value"); } - if(scalar(@keysValues) == 2){ + if ( scalar(@keysValues) == 2 ) { + # for example, -y="defaultIndent: ' '" my $key = $keysValues[0]; $logger->info("Updating mainSettings with $key: $value"); $mainSettings{$key} = $value; - } elsif(scalar(@keysValues) == 3){ + } + elsif ( scalar(@keysValues) == 3 ) { + # for example, -y="indentRules: one: '\t\t\t\t'" my $parent = $keysValues[0]; - my $child = $keysValues[1]; + my $child = $keysValues[1]; $logger->info("Updating mainSettings with $parent: $child: $value"); $mainSettings{$parent}{$child} = $value; - } elsif(scalar(@keysValues) == 4){ + } + elsif ( scalar(@keysValues) == 4 ) { + # for example, -y='modifyLineBreaks : environments: EndStartsOnOwnLine:3' -m - my $parent = $keysValues[0]; - my $child = $keysValues[1]; + my $parent = $keysValues[0]; + my $child = $keysValues[1]; my $grandchild = $keysValues[2]; $logger->info("Updating mainSettings with $parent: $child: $grandchild: $value"); $mainSettings{$parent}{$child}{$grandchild} = $value; - } elsif(scalar(@keysValues) == 5){ + } + elsif ( scalar(@keysValues) == 5 ) { + # for example, -y='modifyLineBreaks : environments: one: EndStartsOnOwnLine:3' -m - my $parent = $keysValues[0]; - my $child = $keysValues[1]; - my $grandchild = $keysValues[2]; + my $parent = $keysValues[0]; + my $child = $keysValues[1]; + my $grandchild = $keysValues[2]; my $greatgrandchild = $keysValues[3]; $logger->info("Updating mainSettings with $parent: $child: $grandchild: $greatgrandchild: $value"); $mainSettings{$parent}{$child}{$grandchild}{$greatgrandchild} = $value; } - + &yaml_update_dumper_settings(); - } + } - } + } - # some users may wish to see showAmalgamatedSettings - # which details the overall state of the settings modified - # from the default in various user files - if($mainSettings{logFilePreferences}{showAmalgamatedSettings}){ - $logger->info("Amalgamated/overall settings to be used:"); - $logger->info(Dumper(\%mainSettings)); - } + # some users may wish to see showAmalgamatedSettings + # which details the overall state of the settings modified + # from the default in various user files + if ( $mainSettings{logFilePreferences}{showAmalgamatedSettings} ) { + $logger->info("Amalgamated/overall settings to be used:"); + $logger->info( Dumper( \%mainSettings ) ); + } - return; + return; } -sub yaml_get_indentation_settings_for_this_object{ +sub yaml_get_indentation_settings_for_this_object { my $self = shift; # create a name for previously found settings - my $storageName = ${$self}{name}.${$self}{modifyLineBreaksYamlName}.(defined ${$self}{storageNameAppend}?${$self}{storageNameAppend}:q()); + my $storageName + = ${$self}{name} + . ${$self}{modifyLineBreaksYamlName} + . ( defined ${$self}{storageNameAppend} ? ${$self}{storageNameAppend} : q() ); # check for storage of repeated objects - if ($previouslyFoundSettings{$storageName}){ - $logger->trace("*Using stored settings for $storageName") if($is_t_switch_active); - } else { + if ( $previouslyFoundSettings{$storageName} ) { + $logger->trace("*Using stored settings for $storageName") if ($is_t_switch_active); + } + else { my $name = ${$self}{name}; - $logger->trace("Storing settings for $storageName") if($is_t_switch_active); + $logger->trace("Storing settings for $storageName") if ($is_t_switch_active); # check for noAdditionalIndent and indentRules # otherwise use defaultIndent @@ -625,47 +719,48 @@ sub yaml_get_indentation_settings_for_this_object{ $self->yaml_modify_line_breaks_settings if $is_m_switch_active; # store the settings - %{${previouslyFoundSettings}{$storageName}} = ( - indentation=>$indentation, - BeginStartsOnOwnLine=>${$self}{BeginStartsOnOwnLine}, - BodyStartsOnOwnLine=>${$self}{BodyStartsOnOwnLine}, - EndStartsOnOwnLine=>${$self}{EndStartsOnOwnLine}, - EndFinishesWithLineBreak=>${$self}{EndFinishesWithLineBreak}, - removeParagraphLineBreaks=>${$self}{removeParagraphLineBreaks}, - textWrapOptions=>${$self}{textWrapOptions}, - columns=>${$self}{columns}, - ); + %{ ${previouslyFoundSettings}{$storageName} } = ( + indentation => $indentation, + BeginStartsOnOwnLine => ${$self}{BeginStartsOnOwnLine}, + BodyStartsOnOwnLine => ${$self}{BodyStartsOnOwnLine}, + EndStartsOnOwnLine => ${$self}{EndStartsOnOwnLine}, + EndFinishesWithLineBreak => ${$self}{EndFinishesWithLineBreak}, + removeParagraphLineBreaks => ${$self}{removeParagraphLineBreaks}, + textWrapOptions => ${$self}{textWrapOptions}, + columns => ${$self}{columns}, + ); # don't forget alignment settings! - foreach (@alignAtAmpersandInformation){ - ${${previouslyFoundSettings}{$storageName}}{${$_}{name}} = ${$self}{${$_}{name}} if(defined ${$self}{${$_}{name}}); - } + foreach (@alignAtAmpersandInformation) { + ${ ${previouslyFoundSettings}{$storageName} }{ ${$_}{name} } = ${$self}{ ${$_}{name} } + if ( defined ${$self}{ ${$_}{name} } ); + } # some objects, e.g ifElseFi, can have extra assignments, e.g ElseStartsOnOwnLine # these need to be stored as well! - foreach (@{${$self}{additionalAssignments}}){ - ${${previouslyFoundSettings}{$storageName}}{$_} = ${$self}{$_}; + foreach ( @{ ${$self}{additionalAssignments} } ) { + ${ ${previouslyFoundSettings}{$storageName} }{$_} = ${$self}{$_}; } # log file information $logger->trace("Settings for $name (stored for future use):") if $is_tt_switch_active; - $logger->trace(Dump \%{${previouslyFoundSettings}{$storageName}}) if $is_tt_switch_active; + $logger->trace( Dump \%{ ${previouslyFoundSettings}{$storageName} } ) if $is_tt_switch_active; } # append indentation settings to the current object - while( my ($key,$value)= each %{${previouslyFoundSettings}{$storageName}}){ - ${$self}{$key} = $value; + while ( my ( $key, $value ) = each %{ ${previouslyFoundSettings}{$storageName} } ) { + ${$self}{$key} = $value; } return; } -sub yaml_alignment_at_ampersand_settings{ +sub yaml_alignment_at_ampersand_settings { my $self = shift; - # if the YamlName is, for example, optionalArguments, mandatoryArguments, heading, then we'll be looking for information about the *parent* - my $name = (defined ${$self}{nameForIndentationSettings}) ? ${$self}{nameForIndentationSettings} : ${$self}{name}; +# if the YamlName is, for example, optionalArguments, mandatoryArguments, heading, then we'll be looking for information about the *parent* + my $name = ( defined ${$self}{nameForIndentationSettings} ) ? ${$self}{nameForIndentationSettings} : ${$self}{name}; # check, for example, # lookForAlignDelims: @@ -673,149 +768,166 @@ sub yaml_alignment_at_ampersand_settings{ # or # # lookForAlignDelims: - # tabular: + # tabular: # delims: 1 # alignDoubleBackSlash: 1 # spacesBeforeDoubleBackSlash: 2 - return unless ${$mainSettings{lookForAlignDelims}}{$name}; - - $logger->trace("alignAtAmpersand settings for $name (see lookForAlignDelims)") if($is_t_switch_active); - - if(ref ${$mainSettings{lookForAlignDelims}}{$name} eq "HASH"){ - # specified as a hash, e.g - # - # lookForAlignDelims: - # tabular: - # delims: 1 - # alignDoubleBackSlash: 1 - # spacesBeforeDoubleBackSlash: 2 - foreach (@alignAtAmpersandInformation){ - my $yamlname = (defined ${$_}{yamlname} ? ${$_}{yamlname}: ${$_}{name}); - - # each of the following cases need to be allowed: - # - # lookForAlignDelims: - # aligned: - # spacesBeforeAmpersand: - # default: 1 - # leadingBlankColumn: 0 - # - # lookForAlignDelims: - # aligned: - # spacesBeforeAmpersand: - # leadingBlankColumn: 0 - # - # lookForAlignDelims: - # aligned: - # spacesBeforeAmpersand: - # default: 0 - # - # approach: - # - update mainSettings to have the relevant information: leadingBlankColumn and/or default - # - delete the spacesBeforeAmpersand hash - # - if ($yamlname eq "spacesBeforeAmpersand" - and ref(${${$mainSettings{lookForAlignDelims}}{$name}}{spacesBeforeAmpersand}) eq "HASH"){ - $logger->trace("spacesBeforeAmpersand settings for $name") if $is_t_switch_active; - + return unless ${ $mainSettings{lookForAlignDelims} }{$name}; + + $logger->trace("alignAtAmpersand settings for $name (see lookForAlignDelims)") if ($is_t_switch_active); + + if ( ref ${ $mainSettings{lookForAlignDelims} }{$name} eq "HASH" ) { + + # specified as a hash, e.g + # + # lookForAlignDelims: + # tabular: + # delims: 1 + # alignDoubleBackSlash: 1 + # spacesBeforeDoubleBackSlash: 2 + foreach (@alignAtAmpersandInformation) { + my $yamlname = ( defined ${$_}{yamlname} ? ${$_}{yamlname} : ${$_}{name} ); + + # each of the following cases need to be allowed: + # # lookForAlignDelims: - # aligned: - # spacesBeforeAmpersand: + # aligned: + # spacesBeforeAmpersand: + # default: 1 # leadingBlankColumn: 0 - if(defined ${${${$mainSettings{lookForAlignDelims}}{$name}}{spacesBeforeAmpersand}}{leadingBlankColumn}){ - $logger->trace("spacesBeforeAmpersand: leadingBlankColumn specified for $name") if $is_t_switch_active; - ${${$mainSettings{lookForAlignDelims}}{$name}}{leadingBlankColumn} - = ${${${$mainSettings{lookForAlignDelims}}{$name}}{spacesBeforeAmpersand}}{leadingBlankColumn}; - } - + # # lookForAlignDelims: - # aligned: - # spacesBeforeAmpersand: + # aligned: + # spacesBeforeAmpersand: + # leadingBlankColumn: 0 + # + # lookForAlignDelims: + # aligned: + # spacesBeforeAmpersand: # default: 0 - if(defined ${${${$mainSettings{lookForAlignDelims}}{$name}}{spacesBeforeAmpersand}}{default}){ - ${${$mainSettings{lookForAlignDelims}}{$name}}{spacesBeforeAmpersand} - = ${${${$mainSettings{lookForAlignDelims}}{$name}}{spacesBeforeAmpersand}}{default}; - } else { - # deleting spacesBeforeAmpersand hash allows spacesBeforeAmpersand - # to pull from the default values @alignAtAmpersandInformation - delete ${${$mainSettings{lookForAlignDelims}}{$name}}{spacesBeforeAmpersand}; + # + # approach: + # - update mainSettings to have the relevant information: leadingBlankColumn and/or default + # - delete the spacesBeforeAmpersand hash + # + if ( $yamlname eq "spacesBeforeAmpersand" + and ref( ${ ${ $mainSettings{lookForAlignDelims} }{$name} }{spacesBeforeAmpersand} ) eq "HASH" ) + { + $logger->trace("spacesBeforeAmpersand settings for $name") if $is_t_switch_active; + + # lookForAlignDelims: + # aligned: + # spacesBeforeAmpersand: + # leadingBlankColumn: 0 + if (defined ${ ${ ${ $mainSettings{lookForAlignDelims} }{$name} }{spacesBeforeAmpersand} } + {leadingBlankColumn} ) + { + $logger->trace("spacesBeforeAmpersand: leadingBlankColumn specified for $name") + if $is_t_switch_active; + ${ ${ $mainSettings{lookForAlignDelims} }{$name} }{leadingBlankColumn} + = ${ ${ ${ $mainSettings{lookForAlignDelims} }{$name} }{spacesBeforeAmpersand} } + {leadingBlankColumn}; + } + + # lookForAlignDelims: + # aligned: + # spacesBeforeAmpersand: + # default: 0 + if ( defined ${ ${ ${ $mainSettings{lookForAlignDelims} }{$name} }{spacesBeforeAmpersand} }{default} ) { + ${ ${ $mainSettings{lookForAlignDelims} }{$name} }{spacesBeforeAmpersand} + = ${ ${ ${ $mainSettings{lookForAlignDelims} }{$name} }{spacesBeforeAmpersand} }{default}; + } + else { + # deleting spacesBeforeAmpersand hash allows spacesBeforeAmpersand + # to pull from the default values @alignAtAmpersandInformation + delete ${ ${ $mainSettings{lookForAlignDelims} }{$name} }{spacesBeforeAmpersand}; + } } - } - ${$self}{ ${$_}{name} } = (defined ${${$mainSettings{lookForAlignDelims}}{$name}}{$yamlname} ) ? ${${$mainSettings{lookForAlignDelims}}{$name}}{$yamlname} : ${$_}{default}; - } - } else { - # specified as a scalar, e.g - # - # lookForAlignDelims: - # tabular: 1 - foreach (@alignAtAmpersandInformation){ - ${$self}{${$_}{name}} = ${$_}{default}; - } + ${$self}{ ${$_}{name} } + = ( defined ${ ${ $mainSettings{lookForAlignDelims} }{$name} }{$yamlname} ) + ? ${ ${ $mainSettings{lookForAlignDelims} }{$name} }{$yamlname} + : ${$_}{default}; + } + } + else { + # specified as a scalar, e.g + # + # lookForAlignDelims: + # tabular: 1 + foreach (@alignAtAmpersandInformation) { + ${$self}{ ${$_}{name} } = ${$_}{default}; + } } return; } -sub yaml_modify_line_breaks_settings{ +sub yaml_modify_line_breaks_settings { my $self = shift; # details to the log file $logger->trace("*-m modifylinebreaks switch active") if $is_t_switch_active; - $logger->trace("looking for polyswitch, textWrapOptions, removeParagraphLineBreaks, oneSentencePerLine settings for ${$self}{name} ") if $is_t_switch_active; + $logger->trace( + "looking for polyswitch, textWrapOptions, removeParagraphLineBreaks, oneSentencePerLine settings for ${$self}{name} " + ) if $is_t_switch_active; # some objects, e.g ifElseFi, can have extra assignments, e.g ElseStartsOnOwnLine - my @toBeAssignedTo = ${$self}{additionalAssignments} ? @{${$self}{additionalAssignments}} : (); + my @toBeAssignedTo = ${$self}{additionalAssignments} ? @{ ${$self}{additionalAssignments} } : (); # the following will *definitley* be in the array, so let's add them - push(@toBeAssignedTo,("BeginStartsOnOwnLine","BodyStartsOnOwnLine","EndStartsOnOwnLine","EndFinishesWithLineBreak")); + push( @toBeAssignedTo, + ( "BeginStartsOnOwnLine", "BodyStartsOnOwnLine", "EndStartsOnOwnLine", "EndFinishesWithLineBreak" ) ); # we can efficiently loop through the following - foreach (@toBeAssignedTo){ - $self->yaml_poly_switch_get_every_or_custom_value( - toBeAssignedTo=>$_, - toBeAssignedToAlias=> ${$self}{aliases}{$_} ? ${$self}{aliases}{$_} : $_, - ); - }; + foreach (@toBeAssignedTo) { + $self->yaml_poly_switch_get_every_or_custom_value( + toBeAssignedTo => $_, + toBeAssignedToAlias => ${$self}{aliases}{$_} ? ${$self}{aliases}{$_} : $_, + ); + } return; } -sub yaml_poly_switch_get_every_or_custom_value{ - my $self = shift; - my %input = @_; - - my $toBeAssignedTo = $input{toBeAssignedTo}; - my $toBeAssignedToAlias = $input{toBeAssignedToAlias}; - - # alias - if(${$self}{aliases}{$toBeAssignedTo}){ - $logger->trace("aliased $toBeAssignedTo using ${$self}{aliases}{$toBeAssignedTo}") if($is_t_switch_active); - } - - # name of the object in the modifyLineBreaks yaml (e.g environments, ifElseFi, etc) - my $YamlName = ${$self}{modifyLineBreaksYamlName}; - - # if the YamlName is either optionalArguments or mandatoryArguments, then we'll be looking for information about the *parent* - my $name = ($YamlName =~ m/Arguments/) ? ${$self}{parent} : ${$self}{name}; - - # these variables just ease the notation what follows - my $everyValue = ${${$mainSettings{modifyLineBreaks}}{$YamlName}}{$toBeAssignedToAlias}; - my $customValue = ${${${$mainSettings{modifyLineBreaks}}{$YamlName}}{$name}}{$toBeAssignedToAlias}; - - # check for the *custom* value - if (defined $customValue){ - $logger->trace("$name: $toBeAssignedToAlias=$customValue, (*per-name* value) adjusting $toBeAssignedTo") if($is_t_switch_active); - ${$self}{$toBeAssignedTo} = $customValue !=0 ? $customValue : undef; - } else { - # check for the *every* value - if (defined $everyValue and $everyValue != 0){ - $logger->trace("$name: $toBeAssignedToAlias=$everyValue, (*global* value) adjusting $toBeAssignedTo") if($is_t_switch_active); - ${$self}{$toBeAssignedTo} = $everyValue; - } - } - return; +sub yaml_poly_switch_get_every_or_custom_value { + my $self = shift; + my %input = @_; + + my $toBeAssignedTo = $input{toBeAssignedTo}; + my $toBeAssignedToAlias = $input{toBeAssignedToAlias}; + + # alias + if ( ${$self}{aliases}{$toBeAssignedTo} ) { + $logger->trace("aliased $toBeAssignedTo using ${$self}{aliases}{$toBeAssignedTo}") if ($is_t_switch_active); + } + + # name of the object in the modifyLineBreaks yaml (e.g environments, ifElseFi, etc) + my $YamlName = ${$self}{modifyLineBreaksYamlName}; + +# if the YamlName is either optionalArguments or mandatoryArguments, then we'll be looking for information about the *parent* + my $name = ( $YamlName =~ m/Arguments/ ) ? ${$self}{parent} : ${$self}{name}; + + # these variables just ease the notation what follows + my $everyValue = ${ ${ $mainSettings{modifyLineBreaks} }{$YamlName} }{$toBeAssignedToAlias}; + my $customValue = ${ ${ ${ $mainSettings{modifyLineBreaks} }{$YamlName} }{$name} }{$toBeAssignedToAlias}; + + # check for the *custom* value + if ( defined $customValue ) { + $logger->trace("$name: $toBeAssignedToAlias=$customValue, (*per-name* value) adjusting $toBeAssignedTo") + if ($is_t_switch_active); + ${$self}{$toBeAssignedTo} = $customValue != 0 ? $customValue : undef; + } + else { + # check for the *every* value + if ( defined $everyValue and $everyValue != 0 ) { + $logger->trace("$name: $toBeAssignedToAlias=$everyValue, (*global* value) adjusting $toBeAssignedTo") + if ($is_t_switch_active); + ${$self}{$toBeAssignedTo} = $everyValue; + } + } + return; } -sub yaml_get_indentation_information{ +sub yaml_get_indentation_information { my $self = shift; #************************************** @@ -834,15 +946,15 @@ sub yaml_get_indentation_information{ # OR # # noAdditionalIndent: - # myexample: + # myexample: # body: 1 # optionalArguments: 1 # mandatoryArguments: 1 - # + # # specifying as a scalar with no field (e.g myexample: 1) # will be interpreted as noAdditionalIndent for *every* # field, so the body, optional arguments and mandatory arguments - # will *all* receive noAdditionalIndent + # will *all* receive noAdditionalIndent # # indentRules can also be a scalar or a hash, e.g # indentRules: @@ -859,31 +971,40 @@ sub yaml_get_indentation_information{ # specifying as a scalar with no field will # mean that *every* field will receive the same treatment - # if the YamlName is, for example, optionalArguments, mandatoryArguments, heading, then we'll be looking for information about the *parent* - my $name = (defined ${$self}{nameForIndentationSettings}) ? ${$self}{nameForIndentationSettings} : ${$self}{name}; +# if the YamlName is, for example, optionalArguments, mandatoryArguments, heading, then we'll be looking for information about the *parent* + my $name = ( defined ${$self}{nameForIndentationSettings} ) ? ${$self}{nameForIndentationSettings} : ${$self}{name}; - # if the YamlName is not optionalArguments, mandatoryArguments, heading (possibly others) then assume we're looking for 'body' +# if the YamlName is not optionalArguments, mandatoryArguments, heading (possibly others) then assume we're looking for 'body' my $YamlName = $self->yaml_get_object_attribute_for_indentation_settings; my $indentationInformation; - foreach my $indentationAbout ("noAdditionalIndent","indentRules"){ + foreach my $indentationAbout ( "noAdditionalIndent", "indentRules" ) { + # check that the 'thing' is defined - if(defined ${$mainSettings{$indentationAbout}}{$name}){ - if(ref ${$mainSettings{$indentationAbout}}{$name} eq "HASH"){ - $logger->trace("$indentationAbout indentation specified with multiple fields for $name, searching for $name: $YamlName (see $indentationAbout)") if $is_t_switch_active ; - $indentationInformation = ${${$mainSettings{$indentationAbout}}{$name}}{$YamlName}; - } else { - $indentationInformation = ${$mainSettings{$indentationAbout}}{$name}; - $logger->trace("$indentationAbout indentation specified for $name (for *all* fields, body, optionalArguments, mandatoryArguments, afterHeading), using '$indentationInformation' (see $indentationAbout)") if $is_t_switch_active ; + if ( defined ${ $mainSettings{$indentationAbout} }{$name} ) { + if ( ref ${ $mainSettings{$indentationAbout} }{$name} eq "HASH" ) { + $logger->trace( + "$indentationAbout indentation specified with multiple fields for $name, searching for $name: $YamlName (see $indentationAbout)" + ) if $is_t_switch_active; + $indentationInformation = ${ ${ $mainSettings{$indentationAbout} }{$name} }{$YamlName}; + } + else { + $indentationInformation = ${ $mainSettings{$indentationAbout} }{$name}; + $logger->trace( + "$indentationAbout indentation specified for $name (for *all* fields, body, optionalArguments, mandatoryArguments, afterHeading), using '$indentationInformation' (see $indentationAbout)" + ) if $is_t_switch_active; } + # return, after performing an integrity check - if(defined $indentationInformation){ - if($indentationAbout eq "noAdditionalIndent" and $indentationInformation == 1){ - $logger->trace("Found! Using '' (see $indentationAbout)") if $is_t_switch_active; - return q(); - } elsif($indentationAbout eq "indentRules" and $indentationInformation=~m/^\h*$/){ - $logger->trace("Found! Using '$indentationInformation' (see $indentationAbout)") if $is_t_switch_active; - return $indentationInformation ; + if ( defined $indentationInformation ) { + if ( $indentationAbout eq "noAdditionalIndent" and $indentationInformation == 1 ) { + $logger->trace("Found! Using '' (see $indentationAbout)") if $is_t_switch_active; + return q(); + } + elsif ( $indentationAbout eq "indentRules" and $indentationInformation =~ m/^\h*$/ ) { + $logger->trace("Found! Using '$indentationInformation' (see $indentationAbout)") + if $is_t_switch_active; + return $indentationInformation; } } } @@ -892,20 +1013,29 @@ sub yaml_get_indentation_information{ # gather information $YamlName = ${$self}{modifyLineBreaksYamlName}; - foreach my $indentationAbout ("noAdditionalIndent","indentRules"){ + foreach my $indentationAbout ( "noAdditionalIndent", "indentRules" ) { + # global assignments in noAdditionalIndentGlobal and/or indentRulesGlobal - my $globalInformation = $indentationAbout."Global"; - next if(!(defined ${$mainSettings{$globalInformation}}{$YamlName})); - if( ($globalInformation eq "noAdditionalIndentGlobal") and ${$mainSettings{$globalInformation}}{$YamlName}==1){ - $logger->trace("$globalInformation specified for $YamlName (see $globalInformation)") if $is_t_switch_active; + my $globalInformation = $indentationAbout . "Global"; + next if ( !( defined ${ $mainSettings{$globalInformation} }{$YamlName} ) ); + if ( ( $globalInformation eq "noAdditionalIndentGlobal" ) + and ${ $mainSettings{$globalInformation} }{$YamlName} == 1 ) + { + $logger->trace("$globalInformation specified for $YamlName (see $globalInformation)") + if $is_t_switch_active; return q(); - } elsif($globalInformation eq "indentRulesGlobal") { - if(${$mainSettings{$globalInformation}}{$YamlName}=~m/^\h*$/){ - $logger->trace("$globalInformation specified for $YamlName (see $globalInformation)") if $is_t_switch_active; - return ${$mainSettings{$globalInformation}}{$YamlName}; - } elsif (${$mainSettings{$globalInformation}}{$YamlName} ne '0') { - $logger->warn("$globalInformation specified (${$mainSettings{$globalInformation}}{$YamlName}) for $YamlName, but it needs to only contain horizontal space -- I'm ignoring this one"); - } + } + elsif ( $globalInformation eq "indentRulesGlobal" ) { + if ( ${ $mainSettings{$globalInformation} }{$YamlName} =~ m/^\h*$/ ) { + $logger->trace("$globalInformation specified for $YamlName (see $globalInformation)") + if $is_t_switch_active; + return ${ $mainSettings{$globalInformation} }{$YamlName}; + } + elsif ( ${ $mainSettings{$globalInformation} }{$YamlName} ne '0' ) { + $logger->warn( + "$globalInformation specified (${$mainSettings{$globalInformation}}{$YamlName}) for $YamlName, but it needs to only contain horizontal space -- I'm ignoring this one" + ); + } } } @@ -914,7 +1044,8 @@ sub yaml_get_indentation_information{ return $mainSettings{defaultIndent}; } -sub yaml_get_object_attribute_for_indentation_settings{ +sub yaml_get_object_attribute_for_indentation_settings { + # when looking for noAdditionalIndent or indentRules, we may need to determine # which thing we're looking for, e.g # @@ -929,16 +1060,16 @@ sub yaml_get_object_attribute_for_indentation_settings{ return "body"; } -sub yaml_update_dumper_settings{ +sub yaml_update_dumper_settings { - # log file preferences - $Data::Dumper::Terse = ${$mainSettings{logFilePreferences}{Dumper}}{Terse}; - $Data::Dumper::Indent = ${$mainSettings{logFilePreferences}{Dumper}}{Indent}; - $Data::Dumper::Useqq = ${$mainSettings{logFilePreferences}{Dumper}}{Useqq}; - $Data::Dumper::Deparse = ${$mainSettings{logFilePreferences}{Dumper}}{Deparse}; - $Data::Dumper::Quotekeys = ${$mainSettings{logFilePreferences}{Dumper}}{Quotekeys}; - $Data::Dumper::Sortkeys = ${$mainSettings{logFilePreferences}{Dumper}}{Sortkeys}; - $Data::Dumper::Pair = ${$mainSettings{logFilePreferences}{Dumper}}{Pair}; + # log file preferences + $Data::Dumper::Terse = ${ $mainSettings{logFilePreferences}{Dumper} }{Terse}; + $Data::Dumper::Indent = ${ $mainSettings{logFilePreferences}{Dumper} }{Indent}; + $Data::Dumper::Useqq = ${ $mainSettings{logFilePreferences}{Dumper} }{Useqq}; + $Data::Dumper::Deparse = ${ $mainSettings{logFilePreferences}{Dumper} }{Deparse}; + $Data::Dumper::Quotekeys = ${ $mainSettings{logFilePreferences}{Dumper} }{Quotekeys}; + $Data::Dumper::Sortkeys = ${ $mainSettings{logFilePreferences}{Dumper} }{Sortkeys}; + $Data::Dumper::Pair = ${ $mainSettings{logFilePreferences}{Dumper} }{Pair}; } 1; diff --git a/Master/texmf-dist/scripts/latexindent/LatexIndent/Heading.pm b/Master/texmf-dist/scripts/latexindent/LatexIndent/Heading.pm index 24d6865c4d5..0a6366f8fa2 100644 --- a/Master/texmf-dist/scripts/latexindent/LatexIndent/Heading.pm +++ b/Master/texmf-dist/scripts/latexindent/LatexIndent/Heading.pm @@ -1,4 +1,5 @@ package LatexIndent::Heading; + # 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 @@ -23,34 +24,38 @@ use LatexIndent::GetYamlSettings qw/%mainSettings/; use LatexIndent::LogFile qw/$logger/; use LatexIndent::Special qw/$specialBeginBasicRegExp/; use Exporter qw/import/; -our @ISA = "LatexIndent::Document"; # class inheritance, Programming Perl, pg 321 +our @ISA = "LatexIndent::Document"; # class inheritance, Programming Perl, pg 321 our @EXPORT_OK = qw/find_heading construct_headings_levels $allHeadingsRegexp/; our $headingCounter; our @headingsRegexpArray; our $allHeadingsRegexp = q(); -sub construct_headings_levels{ +sub construct_headings_levels { my $self = shift; # grab the heading levels - my %headingsLevels = %{$mainSettings{indentAfterHeadings}}; + my %headingsLevels = %{ $mainSettings{indentAfterHeadings} }; # output to log file - $logger->trace("*Constructing headings reg exp for example, chapter, section, etc (see indentAfterThisHeading)") if $is_t_switch_active ; + $logger->trace("*Constructing headings reg exp for example, chapter, section, etc (see indentAfterThisHeading)") + if $is_t_switch_active; # delete the values that have indentAfterThisHeading set to 0 - while( my ($headingName,$headingInfo)= each %headingsLevels){ - if(!${$headingsLevels{$headingName}}{indentAfterThisHeading}){ + while ( my ( $headingName, $headingInfo ) = each %headingsLevels ) { + if ( !${ $headingsLevels{$headingName} }{indentAfterThisHeading} ) { $logger->trace("Not indenting after $headingName (see indentAfterThisHeading)") if $is_t_switch_active; delete $headingsLevels{$headingName}; - } else { + } + else { # *all heading* regexp, remembering to put starred headings at the front of the regexp - if($headingName =~ m/\*/){ - $logger->trace("Putting $headingName at the beginning of the allHeadings regexp, as it contains a *") if $is_t_switch_active ; - $allHeadingsRegexp = $headingName.($allHeadingsRegexp eq '' ?q():"|$allHeadingsRegexp"); - } else { - $logger->trace("Putting $headingName at the END of the allHeadings regexp") if $is_t_switch_active ; - $allHeadingsRegexp .= ($allHeadingsRegexp eq '' ?q():"|").$headingName ; + if ( $headingName =~ m/\*/ ) { + $logger->trace("Putting $headingName at the beginning of the allHeadings regexp, as it contains a *") + if $is_t_switch_active; + $allHeadingsRegexp = $headingName . ( $allHeadingsRegexp eq '' ? q() : "|$allHeadingsRegexp" ); + } + else { + $logger->trace("Putting $headingName at the END of the allHeadings regexp") if $is_t_switch_active; + $allHeadingsRegexp .= ( $allHeadingsRegexp eq '' ? q() : "|" ) . $headingName; } } } @@ -58,54 +63,63 @@ sub construct_headings_levels{ # check for a * in the name $allHeadingsRegexp =~ s/\*/\\\*/g; - # sort the file extensions by preference - my @sortedByLevels = sort { ${$headingsLevels{$a}}{level} <=> $headingsLevels{$b}{level} } keys(%headingsLevels); + # sort the file extensions by preference + my @sortedByLevels = sort { ${ $headingsLevels{$a} }{level} <=> $headingsLevels{$b}{level} } keys(%headingsLevels); # it could be that @sortedByLevels is empty; return if !@sortedByLevels; - $logger->trace("*All headings regexp: $allHeadingsRegexp") if $is_tt_switch_active; - $logger->trace("*Now to construct headings regexp for each level:") if $is_t_switch_active; + $logger->trace("*All headings regexp: $allHeadingsRegexp") if $is_tt_switch_active; + $logger->trace("*Now to construct headings regexp for each level:") if $is_t_switch_active; - # loop through the levels, and create a regexp for each (min and max values are the first and last values respectively from sortedByLevels) - for(my $i = ${$headingsLevels{$sortedByLevels[0]}}{level}; $i <= ${$headingsLevels{$sortedByLevels[-1]}}{level}; $i++ ){ +# loop through the levels, and create a regexp for each (min and max values are the first and last values respectively from sortedByLevels) + for ( + my $i = ${ $headingsLevels{ $sortedByLevels[0] } }{level}; + $i <= ${ $headingsLevels{ $sortedByLevels[-1] } }{level}; + $i++ + ) + { # level regexp - my @tmp = grep { ${$headingsLevels{$_}}{level} == $i } keys %headingsLevels; - if(@tmp){ + my @tmp = grep { ${ $headingsLevels{$_} }{level} == $i } keys %headingsLevels; + if (@tmp) { my $headingsAtThisLevel = q(); - foreach(@tmp){ - # put starred headings at the front of the regexp - if($_ =~ m/\*/){ - $logger->trace("Putting $_ at the beginning of this regexp (level $i), as it contains a *") if $is_t_switch_active; - $headingsAtThisLevel = $_.($headingsAtThisLevel eq '' ?q():"|$headingsAtThisLevel"); - } else { + foreach (@tmp) { + + # put starred headings at the front of the regexp + if ( $_ =~ m/\*/ ) { + $logger->trace("Putting $_ at the beginning of this regexp (level $i), as it contains a *") + if $is_t_switch_active; + $headingsAtThisLevel = $_ . ( $headingsAtThisLevel eq '' ? q() : "|$headingsAtThisLevel" ); + } + else { $logger->trace("Putting $_ at the END of this regexp (level $i)") if $is_t_switch_active; - $headingsAtThisLevel .= ($headingsAtThisLevel eq '' ?q():"|").$_ ; - } + $headingsAtThisLevel .= ( $headingsAtThisLevel eq '' ? q() : "|" ) . $_; + } } # make the stars escaped correctly $headingsAtThisLevel =~ s/\*/\\\*/g; - push(@headingsRegexpArray,$headingsAtThisLevel); - $logger->trace("Heading level regexp for level $i will contain: $headingsAtThisLevel") if $is_t_switch_active; + push( @headingsRegexpArray, $headingsAtThisLevel ); + $logger->trace("Heading level regexp for level $i will contain: $headingsAtThisLevel") + if $is_t_switch_active; } } - } +} -sub find_heading{ +sub find_heading { # if there are no headings regexps, there's no point going any further - return if!@headingsRegexpArray; + return if !@headingsRegexpArray; my $self = shift; # otherwise loop through the headings regexp $logger->trace("*Searching ${$self}{name} for headings ") if $is_t_switch_active; - # loop through each headings match; note that we need to + # loop through each headings match; note that we need to # do it in *reverse* so as to ensure that the lower level headings get matched first of all - foreach(reverse(@headingsRegexpArray)){ - + foreach ( reverse(@headingsRegexpArray) ) { + # the regexp my $headingRegExp = qr/ ( @@ -117,8 +131,8 @@ sub find_heading{ (\R*)? # linebreaks at end of body into $4 ((?:\\(?:$allHeadingsRegexp))|$) # up to another heading, or else the end of the file /sx; - - while(${$self}{body} =~ m/$headingRegExp/){ + + while ( ${$self}{body} =~ m/$headingRegExp/ ) { # log file output $logger->trace("heading found: $2") if $is_t_switch_active; @@ -148,19 +162,19 @@ sub find_heading{ ${@{${$self}{children}}[-1]}{replacementText}; /xse; } - } + } } -sub get_replacement_text{ +sub get_replacement_text { my $self = shift; # the replacement text for a heading (chapter, section, etc) needs to put the trailing part back in $logger->trace("Custom replacement text routine for ${$self}{name}") if $is_t_switch_active; - ${$self}{replacementText} = ${$self}{id}.${$self}{afterbit}; + ${$self}{replacementText} = ${$self}{id} . ${$self}{afterbit}; delete ${$self}{afterbit}; } -sub create_unique_id{ +sub create_unique_id { my $self = shift; $headingCounter++; @@ -169,11 +183,12 @@ sub create_unique_id{ return; } -sub adjust_replacement_text_line_breaks_at_end{ +sub adjust_replacement_text_line_breaks_at_end { return; } -sub yaml_get_object_attribute_for_indentation_settings{ +sub yaml_get_object_attribute_for_indentation_settings { + # when looking for noAdditionalIndent or indentRules, we may need to determine # which thing we're looking for, e.g # @@ -186,11 +201,11 @@ sub yaml_get_object_attribute_for_indentation_settings{ # this method returns 'body' by default, but the other objects (optionalArgument, mandatoryArgument, afterHeading) # return their appropriate identifier. my $self = shift; - + return ${$self}{modifyLineBreaksYamlName}; } -sub tasks_particular_to_each_object{ +sub tasks_particular_to_each_object { my $self = shift; # search for commands, keys, named grouping braces @@ -209,16 +224,21 @@ sub tasks_particular_to_each_object{ # CommandStartsOnOwnLine: 1 # # then we need to transfer this information to the heading object - if($is_m_switch_active){ - $logger->trace("Searching for linebreak preferences immediately infront of ${$self}{parent}") if $is_t_switch_active; - foreach(@{${$self}{children}}){ - if(${$_}{name} eq ${$self}{parent}){ + if ($is_m_switch_active) { + $logger->trace("Searching for linebreak preferences immediately infront of ${$self}{parent}") + if $is_t_switch_active; + foreach ( @{ ${$self}{children} } ) { + if ( ${$_}{name} eq ${$self}{parent} ) { $logger->trace("Named child found: ${$_}{name}") if $is_t_switch_active; - if(defined ${$_}{BeginStartsOnOwnLine}){ - $logger->trace("Transferring information from ${$_}{id} (${$_}{name}) to ${$self}{id} (${$self}{name}) for BeginStartsOnOwnLine") if $is_t_switch_active; + if ( defined ${$_}{BeginStartsOnOwnLine} ) { + $logger->trace( + "Transferring information from ${$_}{id} (${$_}{name}) to ${$self}{id} (${$self}{name}) for BeginStartsOnOwnLine" + ) if $is_t_switch_active; ${$self}{BeginStartsOnOwnLine} = ${$_}{BeginStartsOnOwnLine}; - } else { - $logger->trace("No information found in ${$_}{name} for BeginStartsOnOwnLine") if $is_t_switch_active; + } + else { + $logger->trace("No information found in ${$_}{name} for BeginStartsOnOwnLine") + if $is_t_switch_active; } last; } @@ -231,13 +251,16 @@ sub tasks_particular_to_each_object{ return; } -sub add_surrounding_indentation_to_begin_statement{ - # almost all of the objects add surrounding indentation to the 'begin' statements, +sub add_surrounding_indentation_to_begin_statement { + + # almost all of the objects add surrounding indentation to the 'begin' statements, # but some (e.g HEADING) have their own method my $self = shift; - - $logger->trace("Adding surrounding indentation after (empty, by design!) begin statement of ${$self}{name} (${$self}{id})") if $is_t_switch_active; - ${$self}{begin} .= ${$self}{surroundingIndentation}; # add indentation + + $logger->trace( + "Adding surrounding indentation after (empty, by design!) begin statement of ${$self}{name} (${$self}{id})") + if $is_t_switch_active; + ${$self}{begin} .= ${$self}{surroundingIndentation}; # add indentation } diff --git a/Master/texmf-dist/scripts/latexindent/LatexIndent/HiddenChildren.pm b/Master/texmf-dist/scripts/latexindent/LatexIndent/HiddenChildren.pm index 0e6d9657800..9c01d9b65bf 100644 --- a/Master/texmf-dist/scripts/latexindent/LatexIndent/HiddenChildren.pm +++ b/Master/texmf-dist/scripts/latexindent/LatexIndent/HiddenChildren.pm @@ -1,4 +1,5 @@ package LatexIndent::HiddenChildren; + # 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 @@ -22,22 +23,22 @@ use LatexIndent::LogFile qw/$logger/; use LatexIndent::GetYamlSettings qw/%mainSettings/; use Data::Dumper; use Exporter qw/import/; -our @EXPORT_OK = qw/find_surrounding_indentation_for_children update_family_tree get_family_tree check_for_hidden_children %familyTree hidden_children_preparation_for_alignment unpack_children_into_body/; +our @EXPORT_OK + = qw/find_surrounding_indentation_for_children update_family_tree get_family_tree check_for_hidden_children %familyTree hidden_children_preparation_for_alignment unpack_children_into_body/; # hiddenChildren can be stored in a global array, it doesn't matter what level they're at our %familyTree; our %allChildren; - #---------------------------------------------------------- # Discussion surrounding hidden children # # Consider the following latex code # # \begin{one} -# body of one -# body of one -# body of one +# body of one +# body of one +# body of one # \begin{two} # body of two # body of two @@ -54,157 +55,197 @@ our %allChildren; # * # / \ # / \ -# / \ +# / \ # O O # # where * represents the 'root' document object, and each 'O' is an environment object; the -# first one, on the left, represents <two> and the second one, on the right, represents <one>. +# first one, on the left, represents <two> and the second one, on the right, represents <one>. # (Remember that the environment regexp does not allow \begin within its body.) # # When processing the document, <one> will be processed *before* <two>. Furthermore, because -# <one> and <two> are at the same level, they are not *natural* ancestors of each other; as such, -# we say that <two> is a *hidden* child, and that its 'adopted' ancestor is <one>. +# <one> and <two> are at the same level, they are not *natural* ancestors of each other; as such, +# we say that <two> is a *hidden* child, and that its 'adopted' ancestor is <one>. # -# We need to go to a lot of effort to make sure that <two> knows about its ancestors and its +# We need to go to a lot of effort to make sure that <two> knows about its ancestors and its # surrounding indentation (<one> in this case). The subroutines in this file do that effort. #---------------------------------------------------------- -sub find_surrounding_indentation_for_children{ +sub find_surrounding_indentation_for_children { my $self = shift; # output to logfile $logger->trace("*FamilyTree before update:") if $is_tt_switch_active; - $logger->trace(Dumper(\%familyTree)) if($is_tt_switch_active); + $logger->trace( Dumper( \%familyTree ) ) if ($is_tt_switch_active); # update the family tree with ancestors $self->update_family_tree; # output information to the logfile $logger->trace("*FamilyTree after update:") if $is_tt_switch_active; - $logger->trace(Dumper(\%familyTree)) if($is_tt_switch_active); - - while( my ($idToSearch,$ancestorToSearch) = each %familyTree){ - $logger->trace("*Hidden child ID: ,$idToSearch, here are its ancestors:") if $is_t_switch_active; - foreach(@{${$ancestorToSearch}{ancestors}}){ - $logger->trace("ID: ${$_}{ancestorID}") if($is_t_switch_active); - my $tmpIndentation = ref(${$_}{ancestorIndentation}) eq 'SCALAR'?${${$_}{ancestorIndentation}}:${$_}{ancestorIndentation}; - $tmpIndentation = $tmpIndentation ? $tmpIndentation : q(); - $logger->trace("indentation: '$tmpIndentation'") if($is_t_switch_active); - } - } + $logger->trace( Dumper( \%familyTree ) ) if ($is_tt_switch_active); + + while ( my ( $idToSearch, $ancestorToSearch ) = each %familyTree ) { + $logger->trace("*Hidden child ID: ,$idToSearch, here are its ancestors:") if $is_t_switch_active; + foreach ( @{ ${$ancestorToSearch}{ancestors} } ) { + $logger->trace("ID: ${$_}{ancestorID}") if ($is_t_switch_active); + my $tmpIndentation + = ref( ${$_}{ancestorIndentation} ) eq 'SCALAR' + ? ${ ${$_}{ancestorIndentation} } + : ${$_}{ancestorIndentation}; + $tmpIndentation = $tmpIndentation ? $tmpIndentation : q(); + $logger->trace("indentation: '$tmpIndentation'") if ($is_t_switch_active); + } + } return; } -sub update_family_tree{ +sub update_family_tree { my $self = shift; # loop through the hash $logger->trace("*Updating FamilyTree...") if $is_t_switch_active; - while( my ($idToSearch,$ancestorToSearch)= each %familyTree){ - $logger->trace("*current ID: $idToSearch") if($is_t_switch_active); - foreach(@{${$ancestorToSearch}{ancestors}}){ - my $ancestorID = ${$_}{ancestorID}; - - # construct the natural ancestors - my $naturalAncestors = q(); - foreach(@{${$familyTree{$idToSearch}}{ancestors}}){ - $naturalAncestors .= "---".${$_}{ancestorID} if(${$_}{type} eq "natural"); - } - - # we only need to update the family tree if the $ancestorID is *not* a natural - # ancestor, otherwise everything will be taken care of by the natural ancestor - if($naturalAncestors !~ m/$ancestorID/){ - $logger->trace("ancestor: $ancestorID") if($is_t_switch_active); - if($familyTree{$ancestorID}){ - $logger->trace("$ancestorID is a key within familyTree, grabbing its ancestors") if($is_t_switch_active); - foreach(@{${$familyTree{$ancestorID}}{ancestors}}){ - $logger->trace("ancestor of *hidden* child: ${$_}{ancestorID}") if($is_t_switch_active); - my $newAncestorId = ${$_}{ancestorID}; - my $type; - if($naturalAncestors =~ m/$ancestorID/){ - $type = "natural"; - } else { - $type = "adopted"; + while ( my ( $idToSearch, $ancestorToSearch ) = each %familyTree ) { + $logger->trace("*current ID: $idToSearch") if ($is_t_switch_active); + foreach ( @{ ${$ancestorToSearch}{ancestors} } ) { + my $ancestorID = ${$_}{ancestorID}; + + # construct the natural ancestors + my $naturalAncestors = q(); + foreach ( @{ ${ $familyTree{$idToSearch} }{ancestors} } ) { + $naturalAncestors .= "---" . ${$_}{ancestorID} if ( ${$_}{type} eq "natural" ); + } + + # we only need to update the family tree if the $ancestorID is *not* a natural + # ancestor, otherwise everything will be taken care of by the natural ancestor + if ( $naturalAncestors !~ m/$ancestorID/ ) { + $logger->trace("ancestor: $ancestorID") if ($is_t_switch_active); + if ( $familyTree{$ancestorID} ) { + $logger->trace("$ancestorID is a key within familyTree, grabbing its ancestors") + if ($is_t_switch_active); + foreach ( @{ ${ $familyTree{$ancestorID} }{ancestors} } ) { + $logger->trace("ancestor of *hidden* child: ${$_}{ancestorID}") if ($is_t_switch_active); + my $newAncestorId = ${$_}{ancestorID}; + my $type; + if ( $naturalAncestors =~ m/$ancestorID/ ) { + $type = "natural"; + } + else { + $type = "adopted"; + } + my $matched + = grep { $_->{ancestorID} eq $newAncestorId } @{ ${ $familyTree{$idToSearch} }{ancestors} }; + push( + @{ ${ $familyTree{$idToSearch} }{ancestors} }, + { ancestorID => ${$_}{ancestorID}, + ancestorIndentation => ${$_}{ancestorIndentation}, + type => $type } - my $matched = grep { $_->{ancestorID} eq $newAncestorId } @{${$familyTree{$idToSearch}}{ancestors}}; - push(@{${$familyTree{$idToSearch}}{ancestors}},{ancestorID=>${$_}{ancestorID},ancestorIndentation=>${$_}{ancestorIndentation},type=>$type}) unless($matched); + ) unless ($matched); + } + } + else { + $logger->trace("natural ancestors of $ancestorID: $naturalAncestors") if ($is_t_switch_active); + foreach ( @{ ${ $allChildren{$ancestorID} }{ancestors} } ) { + my $newAncestorId = ${$_}{ancestorID}; + my $type; + if ( $naturalAncestors =~ m/$newAncestorId/ ) { + $type = "natural"; + } + else { + $type = "adopted"; + } + my $matched + = grep { $_->{ancestorID} eq $newAncestorId } @{ ${ $familyTree{$idToSearch} }{ancestors} }; + unless ($matched) { + $logger->trace("ancestor of UNHIDDEN child: ${$_}{ancestorID}") if ($is_t_switch_active); + push( + @{ ${ $familyTree{$idToSearch} }{ancestors} }, + { ancestorID => ${$_}{ancestorID}, + ancestorIndentation => ${$_}{ancestorIndentation}, + type => $type + } + ); } - } else { - $logger->trace("natural ancestors of $ancestorID: $naturalAncestors") if($is_t_switch_active); - foreach(@{${$allChildren{$ancestorID}}{ancestors}}){ - my $newAncestorId = ${$_}{ancestorID}; - my $type; - if($naturalAncestors =~ m/$newAncestorId/){ - $type = "natural"; - } else { - $type = "adopted"; - } - my $matched = grep { $_->{ancestorID} eq $newAncestorId } @{${$familyTree{$idToSearch}}{ancestors}}; - unless($matched){ - $logger->trace("ancestor of UNHIDDEN child: ${$_}{ancestorID}") if($is_t_switch_active); - push(@{${$familyTree{$idToSearch}}{ancestors}},{ancestorID=>${$_}{ancestorID},ancestorIndentation=>${$_}{ancestorIndentation},type=>$type}); - } - } - } - } - } + } + } + } + } } } -sub check_for_hidden_children{ +sub check_for_hidden_children { my $self = shift; my @matched; + # grab the matches - if($is_m_switch_active and ${$mainSettings{modifyLineBreaks}{textWrapOptions}}{huge} ne "overflow"){ + if ( $is_m_switch_active and ${ $mainSettings{modifyLineBreaks}{textWrapOptions} }{huge} ne "overflow" ) { + # if modifyLineBreaks is active, then the IDS can be split across lines - my $ifElseFiSpecialBegin = join("\\R?\\h*",split(//,$tokens{ifelsefiSpecial})); - my $BeginwithLineBreaks = join("\\R?\\h*",split(//,$tokens{beginOfToken})); - my $EndwithLineBreaks = join("\\R?\\h*",split(//,$tokens{endOfToken})); - my $BlankLinesWithLineBreaks = join("\\R?\\h*",split(//,$tokens{blanklines})); - @matched = (${$self}{body} =~ /(?!$BlankLinesWithLineBreaks)((?:$ifElseFiSpecialBegin)?$BeginwithLineBreaks[-a-z0-9\n]+?$EndwithLineBreaks)/ig); + my $ifElseFiSpecialBegin = join( "\\R?\\h*", split( //, $tokens{ifelsefiSpecial} ) ); + my $BeginwithLineBreaks = join( "\\R?\\h*", split( //, $tokens{beginOfToken} ) ); + my $EndwithLineBreaks = join( "\\R?\\h*", split( //, $tokens{endOfToken} ) ); + my $BlankLinesWithLineBreaks = join( "\\R?\\h*", split( //, $tokens{blanklines} ) ); + @matched + = ( ${$self}{body} + =~ /(?!$BlankLinesWithLineBreaks)((?:$ifElseFiSpecialBegin)?$BeginwithLineBreaks[-a-z0-9\n]+?$EndwithLineBreaks)/ig + ); # remove line breaks and horizontal space from matches $_ =~ s/\R|\h//gs foreach (@matched); - } else { - @matched = (${$self}{body} =~ /((?:$tokens{ifelsefiSpecial})?$tokens{beginOfToken}.[-a-z0-9]+?$tokens{endOfToken})/igs); + } + else { + @matched = ( ${$self}{body} + =~ /((?:$tokens{ifelsefiSpecial})?$tokens{beginOfToken}.[-a-z0-9]+?$tokens{endOfToken})/igs ); } # log file $logger->trace("*Hidden children check for ${$self}{name}") if $is_t_switch_active; - $logger->trace(join("|",@matched)) if $is_t_switch_active; + $logger->trace( join( "|", @matched ) ) if $is_t_switch_active; - my $naturalAncestors = ${$self}{naturalAncestors}; + my $naturalAncestors = ${$self}{naturalAncestors}; # loop through the hidden children - foreach my $match (@matched){ + foreach my $match (@matched) { next if $match =~ m/$tokens{verbatim}/; # update the family tree with ancestors of self - if(${$self}{ancestors}){ - foreach(@{${$self}{ancestors}}){ + if ( ${$self}{ancestors} ) { + foreach ( @{ ${$self}{ancestors} } ) { my $newAncestorId = ${$_}{ancestorID}; - unless (grep { $_->{ancestorID} eq $newAncestorId } @{${$familyTree{$match}}{ancestors}}){ - my $type = ($naturalAncestors =~ m/${$_}{ancestorID}/ ) ? "natural" : "adopted"; - $logger->trace("Adding ${$_}{ancestorID} to the $type family tree of $match") if($is_t_switch_active); - push(@{$familyTree{$match}{ancestors}},{ancestorID=>${$_}{ancestorID},ancestorIndentation=>${$_}{ancestorIndentation},type=>$type}); + unless ( grep { $_->{ancestorID} eq $newAncestorId } @{ ${ $familyTree{$match} }{ancestors} } ) { + my $type = ( $naturalAncestors =~ m/${$_}{ancestorID}/ ) ? "natural" : "adopted"; + $logger->trace("Adding ${$_}{ancestorID} to the $type family tree of $match") + if ($is_t_switch_active); + push( + @{ $familyTree{$match}{ancestors} }, + { ancestorID => ${$_}{ancestorID}, + ancestorIndentation => ${$_}{ancestorIndentation}, + type => $type + } + ); } } } # update the family tree with self - unless (grep { $_->{ancestorID} eq ${$self}{id}} @{${$familyTree{$match}}{ancestors}}){ - my $type = ($naturalAncestors =~ m/${$self}{id}/ ) ? "natural" : "adopted"; - $logger->trace("Adding ${$self}{id} to the $type family tree of hiddenChild $match") if($is_t_switch_active); - push(@{$familyTree{$match}{ancestors}},{ancestorID=>${$self}{id},ancestorIndentation=>${$self}{indentation},type=>$type}); - - if(${$self}{lookForAlignDelims}){ - $logger->trace("$match needs measuring for ${$self}{name} (see lookForAlignDelims)") if($is_t_switch_active); - push(@{${$self}{measureHiddenChildren}},$match); - } + unless ( grep { $_->{ancestorID} eq ${$self}{id} } @{ ${ $familyTree{$match} }{ancestors} } ) { + my $type = ( $naturalAncestors =~ m/${$self}{id}/ ) ? "natural" : "adopted"; + $logger->trace("Adding ${$self}{id} to the $type family tree of hiddenChild $match") + if ($is_t_switch_active); + push( + @{ $familyTree{$match}{ancestors} }, + { ancestorID => ${$self}{id}, ancestorIndentation => ${$self}{indentation}, type => $type } + ); + + if ( ${$self}{lookForAlignDelims} ) { + $logger->trace("$match needs measuring for ${$self}{name} (see lookForAlignDelims)") + if ($is_t_switch_active); + push( @{ ${$self}{measureHiddenChildren} }, $match ); + } } } @@ -244,36 +285,37 @@ sub check_for_hidden_children{ # # 3. during the alignment routine, we use 'bodyForMeasure' for measuring the cells # -sub hidden_children_preparation_for_alignment{ +sub hidden_children_preparation_for_alignment { - my $self = shift; + my $self = shift; my $latexIndentObject = shift; - for my $hiddenChildToMeasure (@{${$latexIndentObject}{measureHiddenChildren}}){ - for (@{${$self}{children}}){ - if(${$_}{id} eq $hiddenChildToMeasure){ + for my $hiddenChildToMeasure ( @{ ${$latexIndentObject}{measureHiddenChildren} } ) { + for ( @{ ${$self}{children} } ) { + if ( ${$_}{id} eq $hiddenChildToMeasure ) { - my $bodyForMeasure = ${$_}{begin}.${$_}{body}.${$_}{end}; - for my $child (${$_}{children}){ - $bodyForMeasure = &unpack_children_into_body(\@{$child},$bodyForMeasure); + my $bodyForMeasure = ${$_}{begin} . ${$_}{body} . ${$_}{end}; + for my $child ( ${$_}{children} ) { + $bodyForMeasure = &unpack_children_into_body( \@{$child}, $bodyForMeasure ); } - $familyTree{${$_}{id}}{bodyForMeasure} = $bodyForMeasure; + $familyTree{ ${$_}{id} }{bodyForMeasure} = $bodyForMeasure; } } } return; } -sub unpack_children_into_body{ +sub unpack_children_into_body { my $child = shift; my $body = shift; - for my $individualChild (@{$child}){ - $body =~ s/${$individualChild}{id}/${$individualChild}{begin}${$individualChild}{body}${$individualChild}{end}/s; + for my $individualChild ( @{$child} ) { + $body + =~ s/${$individualChild}{id}/${$individualChild}{begin}${$individualChild}{body}${$individualChild}{end}/s; - if(${$individualChild}{children}){ - for my $nextlevelchild (${$individualChild}{children}){ - $body = &unpack_children_into_body(\@{$nextlevelchild},$body); + if ( ${$individualChild}{children} ) { + for my $nextlevelchild ( ${$individualChild}{children} ) { + $body = &unpack_children_into_body( \@{$nextlevelchild}, $body ); } - } + } } return $body; } diff --git a/Master/texmf-dist/scripts/latexindent/LatexIndent/HorizontalWhiteSpace.pm b/Master/texmf-dist/scripts/latexindent/LatexIndent/HorizontalWhiteSpace.pm index 695e18223f2..3ca67433a84 100644 --- a/Master/texmf-dist/scripts/latexindent/LatexIndent/HorizontalWhiteSpace.pm +++ b/Master/texmf-dist/scripts/latexindent/LatexIndent/HorizontalWhiteSpace.pm @@ -1,4 +1,5 @@ package LatexIndent::HorizontalWhiteSpace; + # 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 @@ -22,16 +23,18 @@ use LatexIndent::LogFile qw/$logger/; use Exporter qw/import/; our @EXPORT_OK = qw/remove_trailing_whitespace remove_leading_space/; -sub remove_trailing_whitespace{ - my $self = shift; +sub remove_trailing_whitespace { + my $self = shift; my %input = @_; $logger->trace("*Horizontal space removal routine") if $is_t_switch_active; # removeTrailingWhitespace can be either a hash or a scalar, but if # it's a scalar, we need to fix it - if(ref($mainSettings{removeTrailingWhitespace}) ne 'HASH'){ - $logger->trace("removeTrailingWhitespace specified as scalar, will update it to be a hash") if $is_t_switch_active; + if ( ref( $mainSettings{removeTrailingWhitespace} ) ne 'HASH' ) { + $logger->trace("removeTrailingWhitespace specified as scalar, will update it to be a hash") + if $is_t_switch_active; + # grab the value my $removeTWS = $mainSettings{removeTrailingWhitespace}; @@ -39,20 +42,26 @@ sub remove_trailing_whitespace{ delete $mainSettings{removeTrailingWhitespace}; # redefine it as a hash - ${$mainSettings{removeTrailingWhitespace}}{beforeProcessing} = $removeTWS; - ${$mainSettings{removeTrailingWhitespace}}{afterProcessing} = $removeTWS; + ${ $mainSettings{removeTrailingWhitespace} }{beforeProcessing} = $removeTWS; + ${ $mainSettings{removeTrailingWhitespace} }{afterProcessing} = $removeTWS; $logger->trace("removeTrailingWhitespace: beforeProcessing is now $removeTWS") if $is_t_switch_active; - $logger->trace("removeTrailingWhitespace: afterProcessing is now $removeTWS") if $is_t_switch_active; + $logger->trace("removeTrailingWhitespace: afterProcessing is now $removeTWS") if $is_t_switch_active; } # this method can be called before the indendation, and after, depending upon the input - if($input{when} eq "before"){ - return unless(${$mainSettings{removeTrailingWhitespace}}{beforeProcessing}); - $logger->trace("Removing trailing white space *before* the document is processed (see removeTrailingWhitespace: beforeProcessing)") if $is_t_switch_active; - } elsif($input{when} eq "after"){ - return unless(${$mainSettings{removeTrailingWhitespace}}{afterProcessing}); - $logger->trace("Removing trailing white space *after* the document is processed (see removeTrailingWhitespace: afterProcessing)") if $is_t_switch_active; - } else { + if ( $input{when} eq "before" ) { + return unless ( ${ $mainSettings{removeTrailingWhitespace} }{beforeProcessing} ); + $logger->trace( + "Removing trailing white space *before* the document is processed (see removeTrailingWhitespace: beforeProcessing)" + ) if $is_t_switch_active; + } + elsif ( $input{when} eq "after" ) { + return unless ( ${ $mainSettings{removeTrailingWhitespace} }{afterProcessing} ); + $logger->trace( + "Removing trailing white space *after* the document is processed (see removeTrailingWhitespace: afterProcessing)" + ) if $is_t_switch_active; + } + else { return; } @@ -63,9 +72,10 @@ sub remove_trailing_whitespace{ } -sub remove_leading_space{ +sub remove_leading_space { my $self = shift; - $logger->trace("*Removing leading space from ${$self}{name} (verbatim/noindentblock already accounted for)") if $is_t_switch_active; + $logger->trace("*Removing leading space from ${$self}{name} (verbatim/noindentblock already accounted for)") + if $is_t_switch_active; ${$self}{body} =~ s/ ( ^ # beginning of the line @@ -75,5 +85,4 @@ sub remove_leading_space{ return; } - 1; diff --git a/Master/texmf-dist/scripts/latexindent/LatexIndent/IfElseFi.pm b/Master/texmf-dist/scripts/latexindent/LatexIndent/IfElseFi.pm index e090845828c..22b3d2eb0fe 100755 --- a/Master/texmf-dist/scripts/latexindent/LatexIndent/IfElseFi.pm +++ b/Master/texmf-dist/scripts/latexindent/LatexIndent/IfElseFi.pm @@ -1,4 +1,5 @@ package LatexIndent::IfElseFi; + # 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 @@ -23,7 +24,7 @@ use LatexIndent::Switches qw/$is_m_switch_active $is_t_switch_active $is_tt_swit use LatexIndent::LogFile qw/$logger/; use LatexIndent::Heading qw/$allHeadingsRegexp/; use Exporter qw/import/; -our @ISA = "LatexIndent::Document"; # class inheritance, Programming Perl, pg 321 +our @ISA = "LatexIndent::Document"; # class inheritance, Programming Perl, pg 321 our @EXPORT_OK = qw/find_ifelsefi construct_ifelsefi_regexp $ifElseFiBasicRegExp/; our $ifElseFiCounter; our $ifElseFiRegExp; @@ -32,7 +33,7 @@ our $ifElseFiBasicRegExp = qr/\\if/; # store the regular expresssion for matching and replacing the \if...\else...\fi statements # note: we search for \else separately in an attempt to keep this regexp a little more managable -sub construct_ifelsefi_regexp{ +sub construct_ifelsefi_regexp { my $ifElseFiNameRegExp = qr/${${$mainSettings{fineTuning}}{ifElseFi}}{name}/; $ifElseFiRegExp = qr/ ( @@ -58,12 +59,12 @@ sub construct_ifelsefi_regexp{ /sx; } -sub find_ifelsefi{ +sub find_ifelsefi { my $self = shift; - while( ${$self}{body} =~ m/$ifElseFiRegExp\h*($trailingCommentRegExp)?/){ + while ( ${$self}{body} =~ m/$ifElseFiRegExp\h*($trailingCommentRegExp)?/ ) { - ${$self}{body} =~ s/ + ${$self}{body} =~ s/ $ifElseFiRegExp(\h*)($trailingCommentRegExp)? / # create a new IfElseFi object @@ -97,58 +98,70 @@ sub find_ifelsefi{ ${@{${$self}{children}}[-1]}{replacementText}.($10?$10:q()).($11?$11:q()); /xse; - } + } return; } -sub post_indentation_check{ +sub post_indentation_check { + # needed to remove leading horizontal space before \else my $self = shift; # loop through \else and \or - foreach ({regExp=>qr/\\else/},{regExp=>qr/\\or/}){ + foreach ( { regExp => qr/\\else/ }, { regExp => qr/\\or/ } ) { my %else = %{$_}; - if(${$self}{body} =~ m/^\h*$else{regExp}/sm - and - !(${$self}{body} =~ m/^\h*$else{regExp}/s and ${$self}{linebreaksAtEnd}{begin}==0) - ){ - $logger->trace("*Adding surrounding indentation to $else{regExp} statement(s) ('${$self}{surroundingIndentation}')") if $is_t_switch_active; + if ( ${$self}{body} =~ m/^\h*$else{regExp}/sm + and !( ${$self}{body} =~ m/^\h*$else{regExp}/s and ${$self}{linebreaksAtEnd}{begin} == 0 ) ) + { + $logger->trace( + "*Adding surrounding indentation to $else{regExp} statement(s) ('${$self}{surroundingIndentation}')") + if $is_t_switch_active; ${$self}{body} =~ s/^\h*($else{regExp})/${$self}{surroundingIndentation}$1/smg; } } return; } -sub tasks_particular_to_each_object{ +sub tasks_particular_to_each_object { my $self = shift; # check for existence of \else statement, and associated line break information $self->check_for_else_statement( - # else name regexp - elseNameRegExp=>qr|\\else|, - # else statements name - ElseStartsOnOwnLine=>"ElseStartsOnOwnLine", - # end statements - ElseFinishesWithLineBreak=>"ElseFinishesWithLineBreak", - # for the YAML settings storage - storageNameAppend=>"else", - # logfile information - logName=>"else", - ); - + + # else name regexp + elseNameRegExp => qr|\\else|, + + # else statements name + ElseStartsOnOwnLine => "ElseStartsOnOwnLine", + + # end statements + ElseFinishesWithLineBreak => "ElseFinishesWithLineBreak", + + # for the YAML settings storage + storageNameAppend => "else", + + # logfile information + logName => "else", + ); + # check for existence of \or statement, and associated line break information $self->check_for_else_statement( - # else name regexp - elseNameRegExp=>qr|\\or|, - # else statements name - ElseStartsOnOwnLine=>"OrStartsOnOwnLine", - # end statements - ElseFinishesWithLineBreak=>"OrFinishesWithLineBreak", - # for the YAML settings storage - storageNameAppend=>"or", - # logfile information - logName=>"or", - ); + + # else name regexp + elseNameRegExp => qr|\\or|, + + # else statements name + ElseStartsOnOwnLine => "OrStartsOnOwnLine", + + # end statements + ElseFinishesWithLineBreak => "OrFinishesWithLineBreak", + + # for the YAML settings storage + storageNameAppend => "or", + + # logfile information + logName => "or", + ); # search for headings (important to do this before looking for commands!) $self->find_heading if ${$self}{body} =~ m/$allHeadingsRegexp/s; @@ -158,46 +171,48 @@ sub tasks_particular_to_each_object{ } -sub indent_begin{ +sub indent_begin { my $self = shift; - # line break checks after \if statement, can get messy if we + + # line break checks after \if statement, can get messy if we # have, for example # \ifnum # something # which might be changed into # \ifnumsomething # which is undeserible - if (defined ${$self}{BodyStartsOnOwnLine} - and ${$self}{BodyStartsOnOwnLine}==-1 - and ${$self}{body} !~ m/^(\h|\\|(?:!-!))/s - ){ + if ( defined ${$self}{BodyStartsOnOwnLine} + and ${$self}{BodyStartsOnOwnLine} == -1 + and ${$self}{body} !~ m/^(\h|\\|(?:!-!))/s ) + { ${$self}{begin} .= " "; } } -sub wrap_up_statement{ +sub wrap_up_statement { my $self = shift; # line break checks *after* \end{statement} - if (defined ${$self}{EndFinishesWithLineBreak} - and ${$self}{EndFinishesWithLineBreak}==-1 - ) { - # add a single horizontal space after the child id, otherwise we can end up + if ( defined ${$self}{EndFinishesWithLineBreak} + and ${$self}{EndFinishesWithLineBreak} == -1 ) + { + # add a single horizontal space after the child id, otherwise we can end up # with things like - # before: + # before: # \fi # text # after: # \fitext - $logger->trace("*Adding a single space after \\fi statement (otherwise \\fi can be comined with next line of text in an unwanted way)") if $is_t_switch_active; - ${$self}{end} =${$self}{end}." "; + $logger->trace( + "*Adding a single space after \\fi statement (otherwise \\fi can be comined with next line of text in an unwanted way)" + ) if $is_t_switch_active; + ${$self}{end} = ${$self}{end} . " "; } $logger->trace("*Finished indenting ${$self}{name}") if $is_t_switch_active; return $self; } - -sub create_unique_id{ +sub create_unique_id { my $self = shift; $ifElseFiCounter++; @@ -206,5 +221,4 @@ sub create_unique_id{ return; } - 1; diff --git a/Master/texmf-dist/scripts/latexindent/LatexIndent/Indent.pm b/Master/texmf-dist/scripts/latexindent/LatexIndent/Indent.pm index fcf15fc1407..404b4bca5b5 100644 --- a/Master/texmf-dist/scripts/latexindent/LatexIndent/Indent.pm +++ b/Master/texmf-dist/scripts/latexindent/LatexIndent/Indent.pm @@ -1,4 +1,5 @@ package LatexIndent::Indent; + # 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 @@ -24,10 +25,11 @@ use LatexIndent::LogFile qw/$logger/; use Text::Tabs; use Data::Dumper; use Exporter qw/import/; -our @EXPORT_OK = qw/indent wrap_up_statement determine_total_indentation indent_begin indent_body indent_end_statement final_indentation_check push_family_tree_to_indent get_surrounding_indentation indent_children_recursively check_for_blank_lines_at_beginning put_blank_lines_back_in_at_beginning add_surrounding_indentation_to_begin_statement post_indentation_check/; +our @EXPORT_OK + = qw/indent wrap_up_statement determine_total_indentation indent_begin indent_body indent_end_statement final_indentation_check push_family_tree_to_indent get_surrounding_indentation indent_children_recursively check_for_blank_lines_at_beginning put_blank_lines_back_in_at_beginning add_surrounding_indentation_to_begin_statement post_indentation_check/; our %familyTree; -sub indent{ +sub indent { my $self = shift; # determine the surrounding and current indentation @@ -43,20 +45,22 @@ sub indent{ $self->indent_end_statement; # output the completed object to the log file - $logger->trace("Complete indented object (${$self}{name}) after indentation:\n${$self}{begin}${$self}{body}${$self}{end}") if $is_tt_switch_active; + $logger->trace( + "Complete indented object (${$self}{name}) after indentation:\n${$self}{begin}${$self}{body}${$self}{end}") + if $is_tt_switch_active; # wrap-up statement $self->wrap_up_statement; return $self; } -sub wrap_up_statement{ +sub wrap_up_statement { my $self = shift; $logger->trace("*Finished indenting ${$self}{name}") if $is_t_switch_active; return $self; - } +} -sub determine_total_indentation{ +sub determine_total_indentation { my $self = shift; # calculate and grab the surrounding indentation @@ -64,35 +68,36 @@ sub determine_total_indentation{ # logfile information my $surroundingIndentation = ${$self}{surroundingIndentation}; - $logger->trace("indenting object ${$self}{name}") if($is_t_switch_active); - (my $during = $surroundingIndentation) =~ s/\t/TAB/g; - $logger->trace("indentation *surrounding* object: '$during'") if($is_t_switch_active); - ($during = ${$self}{indentation}) =~ s/\t/TAB/g; - $logger->trace("indentation *of* object: '$during'") if($is_t_switch_active); - ($during = $surroundingIndentation.${$self}{indentation}) =~ s/\t/TAB/g; - $logger->trace("*total* indentation to be added: '$during'") if($is_t_switch_active); + $logger->trace("indenting object ${$self}{name}") if ($is_t_switch_active); + ( my $during = $surroundingIndentation ) =~ s/\t/TAB/g; + $logger->trace("indentation *surrounding* object: '$during'") if ($is_t_switch_active); + ( $during = ${$self}{indentation} ) =~ s/\t/TAB/g; + $logger->trace("indentation *of* object: '$during'") if ($is_t_switch_active); + ( $during = $surroundingIndentation . ${$self}{indentation} ) =~ s/\t/TAB/g; + $logger->trace("*total* indentation to be added: '$during'") if ($is_t_switch_active); # form the total indentation of the object - ${$self}{indentation} = $surroundingIndentation.${$self}{indentation}; + ${$self}{indentation} = $surroundingIndentation . ${$self}{indentation}; } -sub get_surrounding_indentation{ +sub get_surrounding_indentation { my $self = shift; my $surroundingIndentation = q(); - if($familyTree{${$self}{id}}){ - $logger->trace("Adopted ancestors found!") if($is_t_switch_active); - foreach(@{${$familyTree{${$self}{id}}}{ancestors}}){ - if(${$_}{type} eq "adopted"){ + if ( $familyTree{ ${$self}{id} } ) { + $logger->trace("Adopted ancestors found!") if ($is_t_switch_active); + foreach ( @{ ${ $familyTree{ ${$self}{id} } }{ancestors} } ) { + if ( ${$_}{type} eq "adopted" ) { my $newAncestorId = ${$_}{ancestorID}; - $logger->trace("ancestor ID: $newAncestorId, adding indentation of $newAncestorId to surroundingIndentation of ${$self}{id}") if($is_t_switch_active); - $surroundingIndentation .= ref(${$_}{ancestorIndentation}) eq 'SCALAR' - ? - (${${$_}{ancestorIndentation}}?${${$_}{ancestorIndentation}}:q()) - : - (${$_}{ancestorIndentation}?${$_}{ancestorIndentation}:q()); + $logger->trace( + "ancestor ID: $newAncestorId, adding indentation of $newAncestorId to surroundingIndentation of ${$self}{id}" + ) if ($is_t_switch_active); + $surroundingIndentation .= + ref( ${$_}{ancestorIndentation} ) eq 'SCALAR' + ? ( ${ ${$_}{ancestorIndentation} } ? ${ ${$_}{ancestorIndentation} } : q() ) + : ( ${$_}{ancestorIndentation} ? ${$_}{ancestorIndentation} : q() ); } } } @@ -100,12 +105,13 @@ sub get_surrounding_indentation{ } -sub indent_begin{ +sub indent_begin { + # for most objects, the begin statement is just one line, but there are exceptions, e.g KeyEqualsValuesBraces return; } -sub indent_body{ +sub indent_body { my $self = shift; # output to the logfile @@ -115,57 +121,72 @@ sub indent_body{ $self->count_body_line_breaks if $is_m_switch_active; # some objects need to check for blank line tokens at the beginning - $self->check_for_blank_lines_at_beginning if $is_m_switch_active; + $self->check_for_blank_lines_at_beginning if $is_m_switch_active; # some objects can format their body to align at the & character - $self->align_at_ampersand if (${$self}{lookForAlignDelims} and !${$self}{dontMeasure}); + $self->align_at_ampersand if ( ${$self}{lookForAlignDelims} and !${$self}{dontMeasure} ); # grab the indentation of the object - # NOTE: we need this here, as ${$self}{indentation} can be updated by the align_at_ampersand routine, + # NOTE: we need this here, as ${$self}{indentation} can be updated by the align_at_ampersand routine, # see https://github.com/cmhughes/latexindent.pl/issues/223 for example my $indentation = ${$self}{indentation}; # possibly remove paragraph line breaks - $self->remove_paragraph_line_breaks if ($is_m_switch_active and ${$self}{removeParagraphLineBreaks} and !${$mainSettings{modifyLineBreaks}{removeParagraphLineBreaks}}{beforeTextWrap}); + $self->remove_paragraph_line_breaks + if ($is_m_switch_active + and ${$self}{removeParagraphLineBreaks} + and !${ $mainSettings{modifyLineBreaks}{removeParagraphLineBreaks} }{beforeTextWrap} ); # body indendation - if(${$self}{linebreaksAtEnd}{begin}==1){ - if(${$self}{body} =~ m/^\h*$/s){ + if ( ${$self}{linebreaksAtEnd}{begin} == 1 ) { + if ( ${$self}{body} =~ m/^\h*$/s ) { $logger->trace("Body of ${$self}{name} is empty, not applying indentation") if $is_t_switch_active; - } else { + } + else { # put any existing horizontal space after the current indentation $logger->trace("Entire body of ${$self}{name} receives indendentation") if $is_t_switch_active; - ${$self}{body} =~ s/^(\h*)/$indentation$1/mg; # add indentation + ${$self}{body} =~ s/^(\h*)/$indentation$1/mg; # add indentation } - } elsif(${$self}{linebreaksAtEnd}{begin}==0 and ${$self}{bodyLineBreaks}>0) { - if(${$self}{body} =~ m/ + } + elsif ( ${$self}{linebreaksAtEnd}{begin} == 0 and ${$self}{bodyLineBreaks} > 0 ) { + if (${$self}{body} =~ m/ (.*?) # content of first line \R # first line break (.*$) # rest of body - /sx){ + /sx + ) + { my $bodyFirstLine = $1; my $remainingBody = $2; $logger->trace("first line of body: $bodyFirstLine") if $is_tt_switch_active; - $logger->trace("remaining body (before indentation):\n'$remainingBody'") if($is_tt_switch_active); - + $logger->trace("remaining body (before indentation):\n'$remainingBody'") if ($is_tt_switch_active); + # add the indentation to all the body except first line - $remainingBody =~ s/^/$indentation/mg unless($remainingBody eq ''); # add indentation - $logger->trace("remaining body (after indentation):\n$remainingBody'") if($is_tt_switch_active); - + $remainingBody =~ s/^/$indentation/mg unless ( $remainingBody eq '' ); # add indentation + $logger->trace("remaining body (after indentation):\n$remainingBody'") if ($is_tt_switch_active); + # put the body back together - ${$self}{body} = $bodyFirstLine."\n".$remainingBody; + ${$self}{body} = $bodyFirstLine . "\n" . $remainingBody; } } # some objects need a post-indentation check, e.g ifElseFi $self->post_indentation_check; + # if the routine check_for_blank_lines_at_beginning has been called, then the following routine - # puts blank line tokens back in - $self->put_blank_lines_back_in_at_beginning if $is_m_switch_active; + # puts blank line tokens back in + $self->put_blank_lines_back_in_at_beginning if $is_m_switch_active; # the final linebreak can be modified by a child object; see test-cases/commands/figureValign-mod5.tex, for example - if($is_m_switch_active and defined ${$self}{linebreaksAtEnd}{body} and ${$self}{linebreaksAtEnd}{body}==1 and ${$self}{body} !~ m/\R$/ and ${$self}{body} ne ''){ - $logger->trace("Adding a linebreak at end of body for ${$self}{name} to contain a linebreak at the end (linebreaksAtEnd is 1, but there isn't currently a linebreak)") if($is_t_switch_active); + if ( $is_m_switch_active + and defined ${$self}{linebreaksAtEnd}{body} + and ${$self}{linebreaksAtEnd}{body} == 1 + and ${$self}{body} !~ m/\R$/ + and ${$self}{body} ne '' ) + { + $logger->trace( + "Adding a linebreak at end of body for ${$self}{name} to contain a linebreak at the end (linebreaksAtEnd is 1, but there isn't currently a linebreak)" + ) if ($is_t_switch_active); ${$self}{body} .= "\n"; } @@ -174,38 +195,46 @@ sub indent_body{ return $self; } -sub post_indentation_check{ +sub post_indentation_check { return; } -sub check_for_blank_lines_at_beginning{ +sub check_for_blank_lines_at_beginning { + # some objects need this routine return; } -sub put_blank_lines_back_in_at_beginning{ +sub put_blank_lines_back_in_at_beginning { + # some objects need this routine return; } -sub indent_end_statement{ +sub indent_end_statement { my $self = shift; - my $surroundingIndentation = (${$self}{surroundingIndentation} and $familyTree{${$self}{id}}) - ? - (ref(${$self}{surroundingIndentation}) eq 'SCALAR'?${${$self}{surroundingIndentation}}:${$self}{surroundingIndentation}) - :q(); + my $surroundingIndentation + = ( ${$self}{surroundingIndentation} and $familyTree{ ${$self}{id} } ) + ? ( + ref( ${$self}{surroundingIndentation} ) eq 'SCALAR' + ? ${ ${$self}{surroundingIndentation} } + : ${$self}{surroundingIndentation} + ) + : q(); # end{statement} indentation, e.g \end{environment}, \fi, }, etc - if(${$self}{linebreaksAtEnd}{body}){ - ${$self}{end} =~ s/^\h*/$surroundingIndentation/mg; # add indentation - $logger->trace("Adding surrounding indentation to ${$self}{end} (${$self}{name}: '$surroundingIndentation')") if($is_t_switch_active); - } + if ( ${$self}{linebreaksAtEnd}{body} ) { + ${$self}{end} =~ s/^\h*/$surroundingIndentation/mg; # add indentation + $logger->trace("Adding surrounding indentation to ${$self}{end} (${$self}{name}: '$surroundingIndentation')") + if ($is_t_switch_active); + } return $self; } -sub final_indentation_check{ +sub final_indentation_check { + # problem: - # if a tab is appended to spaces, it will look different + # if a tab is appended to spaces, it will look different # from spaces appended to tabs (see test-cases/items/spaces-and-tabs.tex) # solution: # move all of the tabs to the beginning of ${$self}{indentation} @@ -215,7 +244,7 @@ sub final_indentation_check{ my $self = shift; my $indentation; - my $numberOfTABS; + my $numberOfTABS; my $after; ${$self}{body} =~ s/ ^((\h*|\t*)((\h+)(\t+))+) @@ -236,80 +265,84 @@ sub final_indentation_check{ $indentation; /xsmeg; - return unless($mainSettings{maximumIndentation} =~ m/^\h+$/); + return unless ( $mainSettings{maximumIndentation} =~ m/^\h+$/ ); # maximum indentation check - $logger->trace("*Maximum indentation check") if($is_t_switch_active); + $logger->trace("*Maximum indentation check") if ($is_t_switch_active); # replace any leading tabs with spaces, and update the body - my @expanded_lines = expand(${$self}{body}); - ${$self}{body} = join("",@expanded_lines); + my @expanded_lines = expand( ${$self}{body} ); + ${$self}{body} = join( "", @expanded_lines ); # grab the maximum indentation - my $maximumIndentation = $mainSettings{maximumIndentation}; - my $maximumIndentationLength = length($maximumIndentation)+1; + my $maximumIndentation = $mainSettings{maximumIndentation}; + my $maximumIndentationLength = length($maximumIndentation) + 1; - # replace any leading space that is greater than the + # replace any leading space that is greater than the # specified maximum indentation with the maximum indentation ${$self}{body} =~ s/^\h{$maximumIndentationLength,}/$maximumIndentation/smg; } -sub indent_children_recursively{ +sub indent_children_recursively { my $self = shift; - unless(defined ${$self}{children}) { + unless ( defined ${$self}{children} ) { $logger->trace("No child objects (${$self}{name})") if $is_t_switch_active; return; } $logger->trace('Pre-processed body:') if $is_tt_switch_active; - $logger->trace(${$self}{body}) if($is_tt_switch_active); + $logger->trace( ${$self}{body} ) if ($is_tt_switch_active); # send the children through this indentation routine recursively - if(defined ${$self}{children}){ - foreach my $child (@{${$self}{children}}){ + if ( defined ${$self}{children} ) { + foreach my $child ( @{ ${$self}{children} } ) { $logger->trace("Indenting child objects on ${$child}{name}") if $is_t_switch_active; $child->indent_children_recursively; } - } + } $logger->trace("*Replacing ids with begin, body, and end statements:") if $is_t_switch_active; # loop through document children hash - while( scalar (@{${$self}{children}}) > 0 ){ - my $index = 0; - # we work through the array *in order* - foreach my $child (@{${$self}{children}}){ + while ( scalar( @{ ${$self}{children} } ) > 0 ) { + my $index = 0; + + # we work through the array *in order* + foreach my $child ( @{ ${$self}{children} } ) { $logger->trace("Searching ${$self}{name} for ${$child}{id}...") if $is_t_switch_active; - if(${$self}{body} =~ m/${$child}{idRegExp}/s){ - # we only care if id is first non-white space character - # and if followed by line break - # if m switch is active - my $IDFirstNonWhiteSpaceCharacter = 0; + if ( ${$self}{body} =~ m/${$child}{idRegExp}/s ) { + + # we only care if id is first non-white space character + # and if followed by line break + # if m switch is active + my $IDFirstNonWhiteSpaceCharacter = 0; my $IDFollowedImmediatelyByLineBreak = 0; # update the above two, if necessary - if ($is_m_switch_active){ - $IDFirstNonWhiteSpaceCharacter = (${$self}{body} =~ m/^${$child}{idRegExp}/m - or - ${$self}{body} =~ m/^\h\h*${$child}{idRegExp}/m - ) ?1:0; - $IDFollowedImmediatelyByLineBreak = (${$self}{body} =~ m/${$child}{idRegExp}\h*\R+/m) ?1:0; - ${$child}{IDFollowedImmediatelyByLineBreak} = $IDFollowedImmediatelyByLineBreak; - } + if ($is_m_switch_active) { + $IDFirstNonWhiteSpaceCharacter = ( + ${$self}{body} =~ m/^${$child}{idRegExp}/m + or ${$self}{body} =~ m/^\h\h*${$child}{idRegExp}/m + ) ? 1 : 0; + $IDFollowedImmediatelyByLineBreak = ( ${$self}{body} =~ m/${$child}{idRegExp}\h*\R+/m ) ? 1 : 0; + ${$child}{IDFollowedImmediatelyByLineBreak} = $IDFollowedImmediatelyByLineBreak; + } # log file info - $logger->trace("${$child}{id} found!") if($is_t_switch_active); - $logger->trace("*Indenting ${$child}{name} (id: ${$child}{id})") if $is_t_switch_active; - $logger->trace("looking up indentation scheme for ${$child}{name}") if($is_t_switch_active); + $logger->trace("${$child}{id} found!") if ($is_t_switch_active); + $logger->trace("*Indenting ${$child}{name} (id: ${$child}{id})") if $is_t_switch_active; + $logger->trace("looking up indentation scheme for ${$child}{name}") if ($is_t_switch_active); # line break checks *after* <end statement> - if (defined ${$child}{EndFinishesWithLineBreak} - and ${$child}{EndFinishesWithLineBreak}==-1 - and $IDFollowedImmediatelyByLineBreak) { + if ( defined ${$child}{EndFinishesWithLineBreak} + and ${$child}{EndFinishesWithLineBreak} == -1 + and $IDFollowedImmediatelyByLineBreak ) + { # remove line break *after* <end statement>, if appropriate - my $EndStringLogFile = ${$child}{aliases}{EndFinishesWithLineBreak}||"EndFinishesWithLineBreak"; - $logger->trace("Removing linebreak after ${$child}{end} (see $EndStringLogFile)") if $is_t_switch_active; + my $EndStringLogFile = ${$child}{aliases}{EndFinishesWithLineBreak} || "EndFinishesWithLineBreak"; + $logger->trace("Removing linebreak after ${$child}{end} (see $EndStringLogFile)") + if $is_t_switch_active; ${$self}{body} =~ s/${$child}{idRegExp}(\h*)?(\R|\h)*/${$child}{id}$1/s; ${$child}{linebreaksAtEnd}{end} = 0; } @@ -318,16 +351,20 @@ sub indent_children_recursively{ $child->indent; # surrounding indentation is now up to date - my $surroundingIndentation = (${$child}{surroundingIndentation} and ${$child}{hiddenChildYesNo}) - ? - (ref(${$child}{surroundingIndentation}) eq 'SCALAR'?${${$child}{surroundingIndentation}}:${$child}{surroundingIndentation}) - :q(); + my $surroundingIndentation + = ( ${$child}{surroundingIndentation} and ${$child}{hiddenChildYesNo} ) + ? ( + ref( ${$child}{surroundingIndentation} ) eq 'SCALAR' + ? ${ ${$child}{surroundingIndentation} } + : ${$child}{surroundingIndentation} + ) + : q(); # line break checks before <begin statement> - if(defined ${$child}{BeginStartsOnOwnLine} and ${$child}{BeginStartsOnOwnLine} !=0 ){ - my $BeginStringLogFile = ${$child}{aliases}{BeginStartsOnOwnLine}||"BeginStartsOnOwnLine"; + if ( defined ${$child}{BeginStartsOnOwnLine} and ${$child}{BeginStartsOnOwnLine} != 0 ) { + my $BeginStringLogFile = ${$child}{aliases}{BeginStartsOnOwnLine} || "BeginStartsOnOwnLine"; - # + # # Blank line poly-switch notes (==4) # # when BeginStartsOnOwnLine=4 we adopt the following approach: @@ -335,92 +372,119 @@ sub indent_children_recursively{ # temporarily change BeginStartsOnOwnLine to 3, make adjustments # # we use an array, @polySwitchValues to facilitate this - my @polySwitchValues = (${$child}{BeginStartsOnOwnLine}==4)?(-1,3):(${$child}{BeginStartsOnOwnLine}); + my @polySwitchValues + = ( ${$child}{BeginStartsOnOwnLine} == 4 ) ? ( -1, 3 ) : ( ${$child}{BeginStartsOnOwnLine} ); - foreach(@polySwitchValues){ - # if BeginStartsOnOwnLine is 4, then we hack - # $IDFirstNonWhiteSpaceCharacter + foreach (@polySwitchValues) { + + # if BeginStartsOnOwnLine is 4, then we hack + # $IDFirstNonWhiteSpaceCharacter # to be 0 on the second time through (poly-switch set to 3) - $IDFirstNonWhiteSpaceCharacter = 0 if (${$child}{BeginStartsOnOwnLine}==4 and $_==3); + $IDFirstNonWhiteSpaceCharacter = 0 if ( ${$child}{BeginStartsOnOwnLine} == 4 and $_ == 3 ); - # if the child ID is not the first character and BeginStartsOnOwnLine>=1 + # if the child ID is not the first character and BeginStartsOnOwnLine>=1 # then we will need to add a line break (==1), a comment (==2) or another blank line (==3) - if($_>=1 and !$IDFirstNonWhiteSpaceCharacter){ + if ( $_ >= 1 and !$IDFirstNonWhiteSpaceCharacter ) { + # by default, assume that no trailing comment token is needed my $trailingCharacterToken = q(); - if($_==2){ - $logger->trace("Removing space immediately before ${$child}{id}, in preparation for adding % ($BeginStringLogFile == 2)") if $is_t_switch_active; + if ( $_ == 2 ) { + $logger->trace( + "Removing space immediately before ${$child}{id}, in preparation for adding % ($BeginStringLogFile == 2)" + ) if $is_t_switch_active; ${$self}{body} =~ s/\h*${$child}{idRegExp}/${$child}{id}/s; - $logger->trace("Adding a % at the end of the line that ${$child}{begin} is on, then a linebreak ($BeginStringLogFile == 2)") if $is_t_switch_active; - $trailingCharacterToken = "%".$self->add_comment_symbol; - } elsif ($_==3){ - $logger->trace("Adding a blank line at the end of the line that ${$child}{begin} is on, then a linebreak ($BeginStringLogFile == 3)") if $is_t_switch_active; - $trailingCharacterToken = "\n".(${$mainSettings{modifyLineBreaks}}{preserveBlankLines}?$tokens{blanklines}:q()); - } else { - $logger->trace("Adding a linebreak at the beginning of ${$child}{begin} (see $BeginStringLogFile)") if $is_t_switch_active; + $logger->trace( + "Adding a % at the end of the line that ${$child}{begin} is on, then a linebreak ($BeginStringLogFile == 2)" + ) if $is_t_switch_active; + $trailingCharacterToken = "%" . $self->add_comment_symbol; + } + elsif ( $_ == 3 ) { + $logger->trace( + "Adding a blank line at the end of the line that ${$child}{begin} is on, then a linebreak ($BeginStringLogFile == 3)" + ) if $is_t_switch_active; + $trailingCharacterToken = "\n" + . ( + ${ $mainSettings{modifyLineBreaks} }{preserveBlankLines} + ? $tokens{blanklines} + : q() + ); + } + else { + $logger->trace( + "Adding a linebreak at the beginning of ${$child}{begin} (see $BeginStringLogFile)") + if $is_t_switch_active; } # the trailing comment/linebreak magic - ${$child}{begin} = "$trailingCharacterToken\n".${$child}{begin}; + ${$child}{begin} = "$trailingCharacterToken\n" . ${$child}{begin}; $child->add_surrounding_indentation_to_begin_statement; # remove surrounding indentation ahead of % - ${$child}{begin} =~ s/^(\h*)%/%/ if($_==2); - } elsif ($_==-1 and $IDFirstNonWhiteSpaceCharacter){ + ${$child}{begin} =~ s/^(\h*)%/%/ if ( $_ == 2 ); + } + elsif ( $_ == -1 and $IDFirstNonWhiteSpaceCharacter ) { + # finally, if BeginStartsOnOwnLine == -1 then we might need to *remove* a blank line(s) # important to check we don't move the begin statement next to a blank-line-token my $blankLineToken = $tokens{blanklines}; - if(${$self}{body} !~ m/$blankLineToken\R*\h*${$child}{idRegExp}/s){ - $logger->trace("Removing linebreak before ${$child}{begin} (see $BeginStringLogFile in ${$child}{modifyLineBreaksYamlName} YAML)") if $is_t_switch_active; + if ( ${$self}{body} !~ m/$blankLineToken\R*\h*${$child}{idRegExp}/s ) { + $logger->trace( + "Removing linebreak before ${$child}{begin} (see $BeginStringLogFile in ${$child}{modifyLineBreaksYamlName} YAML)" + ) if $is_t_switch_active; ${$self}{body} =~ s/(\h*)(?:\R*|\h*)+${$child}{idRegExp}/$1${$child}{id}/s; - } else { - $logger->trace("Not removing linebreak ahead of ${$child}{begin}, as blank-line-token present (see preserveBlankLines)") if $is_t_switch_active; + } + else { + $logger->trace( + "Not removing linebreak ahead of ${$child}{begin}, as blank-line-token present (see preserveBlankLines)" + ) if $is_t_switch_active; } } - } + } } - $logger->trace(Dumper(\%{$child})) if($is_tt_switch_active); + $logger->trace( Dumper( \%{$child} ) ) if ($is_tt_switch_active); # replace ids with body ${$self}{body} =~ s/${$child}{idRegExp}/${$child}{begin}${$child}{body}${$child}{end}/; # log file info $logger->trace("Body (${$self}{name}) now looks like:") if $is_tt_switch_active; - $logger->trace(${$self}{body}) if($is_tt_switch_active); + $logger->trace( ${$self}{body} ) if ($is_tt_switch_active); - # remove element from array: http://stackoverflow.com/questions/174292/what-is-the-best-way-to-delete-a-value-from-an-array-in-perl - splice(@{${$self}{children}}, $index, 1); +# remove element from array: http://stackoverflow.com/questions/174292/what-is-the-best-way-to-delete-a-value-from-an-array-in-perl + splice( @{ ${$self}{children} }, $index, 1 ); # output to the log file $logger->trace("deleted child key ${$child}{name} (parent is: ${$self}{name})") if $is_t_switch_active; # restart the loop, as the size of the array has changed last; - } else { - $logger->trace("${$child}{id} not found") if($is_t_switch_active); - } - - # increment the loop counter - $index++; } + else { + $logger->trace("${$child}{id} not found") if ($is_t_switch_active); + } + + # increment the loop counter + $index++; + } } # logfile info $logger->trace("${$self}{name} has this many children:") if $is_tt_switch_active; - $logger->trace(scalar @{${$self}{children}}) if $is_tt_switch_active; - $logger->trace("Post-processed body (${$self}{name}):") if($is_tt_switch_active); - $logger->trace(${$self}{body}) if($is_tt_switch_active); + $logger->trace( scalar @{ ${$self}{children} } ) if $is_tt_switch_active; + $logger->trace("Post-processed body (${$self}{name}):") if ($is_tt_switch_active); + $logger->trace( ${$self}{body} ) if ($is_tt_switch_active); } -sub add_surrounding_indentation_to_begin_statement{ - # almost all of the objects add surrounding indentation to the 'begin' statements, +sub add_surrounding_indentation_to_begin_statement { + + # almost all of the objects add surrounding indentation to the 'begin' statements, # but some (e.g HEADING) have their own method my $self = shift; my $surroundingIndentation = ${$self}{surroundingIndentation}; - ${$self}{begin} =~ s/^(\h*)?/$surroundingIndentation/mg; # add indentation + ${$self}{begin} =~ s/^(\h*)?/$surroundingIndentation/mg; # add indentation } diff --git a/Master/texmf-dist/scripts/latexindent/LatexIndent/Item.pm b/Master/texmf-dist/scripts/latexindent/LatexIndent/Item.pm index 315e2c35e04..0e7201a8009 100644 --- a/Master/texmf-dist/scripts/latexindent/LatexIndent/Item.pm +++ b/Master/texmf-dist/scripts/latexindent/LatexIndent/Item.pm @@ -1,4 +1,5 @@ package LatexIndent::Item; + # 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 @@ -26,20 +27,20 @@ use LatexIndent::Special qw/$specialBeginAndBracesBracketsBasicRegExp/; use LatexIndent::Heading qw/$allHeadingsRegexp/; use Data::Dumper; use Exporter qw/import/; -our @ISA = "LatexIndent::Document"; # class inheritance, Programming Perl, pg 321 +our @ISA = "LatexIndent::Document"; # class inheritance, Programming Perl, pg 321 our @EXPORT_OK = qw/find_items construct_list_of_items $listOfItems/; our $itemCounter; our $listOfItems = q(); -our $itemRegExp; +our $itemRegExp; -sub construct_list_of_items{ +sub construct_list_of_items { my $self = shift; $listOfItems = q(); # put together a list of the items - while( my ($item,$lookForThisItem)= each %{$mainSettings{itemNames}}){ - $listOfItems .= ($listOfItems eq "")?"$item":"|$item" if($lookForThisItem); + while ( my ( $item, $lookForThisItem ) = each %{ $mainSettings{itemNames} } ) { + $listOfItems .= ( $listOfItems eq "" ) ? "$item" : "|$item" if ($lookForThisItem); } # detail items in the log @@ -62,22 +63,23 @@ sub construct_list_of_items{ ) (\R)? /sx; - return; } -sub find_items{ +sub find_items { + # no point carrying on if the list of items is empty - return if($listOfItems eq ""); + return if ( $listOfItems eq "" ); my $self = shift; # otherwise loop through the item names - $logger->trace("Searching for items (see itemNames) in ${$self}{name} (see indentAfterItems)") if $is_t_switch_active; - $logger->trace(Dumper(\%{$mainSettings{itemNames}})) if $is_tt_switch_active; + $logger->trace("Searching for items (see itemNames) in ${$self}{name} (see indentAfterItems)") + if $is_t_switch_active; + $logger->trace( Dumper( \%{ $mainSettings{itemNames} } ) ) if $is_tt_switch_active; - while(${$self}{body} =~ m/$itemRegExp\h*($trailingCommentRegExp)?/){ + while ( ${$self}{body} =~ m/$itemRegExp\h*($trailingCommentRegExp)?/ ) { # log file output $logger->trace("*Item found: $2") if $is_t_switch_active; @@ -111,8 +113,7 @@ sub find_items{ } } - -sub create_unique_id{ +sub create_unique_id { my $self = shift; $itemCounter++; @@ -121,31 +122,34 @@ sub create_unique_id{ return; } -sub tasks_particular_to_each_object{ +sub tasks_particular_to_each_object { my $self = shift; # the item body could hoover up line breaks; we do an additional check - ${${$self}{linebreaksAtEnd}}{body}=1 if(${$self}{body} =~ m/\R+$/s ); + ${ ${$self}{linebreaksAtEnd} }{body} = 1 if ( ${$self}{body} =~ m/\R+$/s ); # search for ifElseFi blocks $self->find_ifelsefi if ${$self}{body} =~ m/$ifElseFiBasicRegExp/s; # search for headings (part, chapter, section, setc) $self->find_heading if ${$self}{body} =~ m/$allHeadingsRegexp/s; - + # search for commands and special code blocks - $self->find_commands_or_key_equals_values_braces_and_special if ${$self}{body} =~ m/$specialBeginAndBracesBracketsBasicRegExp/s; + $self->find_commands_or_key_equals_values_braces_and_special + if ${$self}{body} =~ m/$specialBeginAndBracesBracketsBasicRegExp/s; } -sub remove_line_breaks_begin{ +sub remove_line_breaks_begin { + # the \item command can need a trailing white space if the line breaks have been removed after it and # there is no white space - my $self = shift; - my $BodyStringLogFile = ${$self}{aliases}{BodyStartsOnOwnLine}||"BodyStartsOnOwnLine"; + my $self = shift; + my $BodyStringLogFile = ${$self}{aliases}{BodyStartsOnOwnLine} || "BodyStartsOnOwnLine"; $logger->trace("Removing linebreak at the end of begin (see $BodyStringLogFile)"); ${$self}{begin} =~ s/\R*$//sx; - ${$self}{begin} .= " " unless(${$self}{begin} =~ m/\h$/s or ${$self}{body} =~ m/^\h/s or ${$self}{body} =~ m/^\R/s ); + ${$self}{begin} .= " " + unless ( ${$self}{begin} =~ m/\h$/s or ${$self}{body} =~ m/^\h/s or ${$self}{body} =~ m/^\R/s ); ${$self}{linebreaksAtEnd}{begin} = 0; } diff --git a/Master/texmf-dist/scripts/latexindent/LatexIndent/KeyEqualsValuesBraces.pm b/Master/texmf-dist/scripts/latexindent/LatexIndent/KeyEqualsValuesBraces.pm index f7090c3d714..684146e2f45 100755 --- a/Master/texmf-dist/scripts/latexindent/LatexIndent/KeyEqualsValuesBraces.pm +++ b/Master/texmf-dist/scripts/latexindent/LatexIndent/KeyEqualsValuesBraces.pm @@ -1,4 +1,5 @@ package LatexIndent::KeyEqualsValuesBraces; + # 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 @@ -22,13 +23,14 @@ use LatexIndent::TrailingComments qw/$trailingCommentRegExp/; use LatexIndent::Switches qw/$is_m_switch_active $is_t_switch_active $is_tt_switch_active/; use LatexIndent::LogFile qw/$logger/; use Exporter qw/import/; -our @ISA = "LatexIndent::Command"; # class inheritance, Programming Perl, pg 321 -our @EXPORT_OK = qw/construct_key_equals_values_regexp $key_equals_values_bracesRegExp $key_equals_values_bracesRegExpTrailingComment/; +our @ISA = "LatexIndent::Command"; # class inheritance, Programming Perl, pg 321 +our @EXPORT_OK + = qw/construct_key_equals_values_regexp $key_equals_values_bracesRegExp $key_equals_values_bracesRegExpTrailingComment/; our $key_equals_values_braces_Counter; -our $key_equals_values_bracesRegExp; -our $key_equals_values_bracesRegExpTrailingComment; +our $key_equals_values_bracesRegExp; +our $key_equals_values_bracesRegExpTrailingComment; -sub construct_key_equals_values_regexp{ +sub construct_key_equals_values_regexp { my $self = shift; # grab the arguments regexp @@ -38,10 +40,11 @@ sub construct_key_equals_values_regexp{ my $blankLineToken = $tokens{blanklines}; # read from fine tuning - my $keyEqualsValuesBracesBrackets = qr/${${$mainSettings{fineTuning}}{keyEqualsValuesBracesBrackets}}{name}/; - my $keyEqualsValuesBracesBracketsFollow = qr/${${$mainSettings{fineTuning}}{keyEqualsValuesBracesBrackets}}{follow}/; + my $keyEqualsValuesBracesBrackets = qr/${${$mainSettings{fineTuning}}{keyEqualsValuesBracesBrackets}}{name}/; + my $keyEqualsValuesBracesBracketsFollow + = qr/${${$mainSettings{fineTuning}}{keyEqualsValuesBracesBrackets}}{follow}/; - # store the regular expresssion for matching and replacing + # store the regular expresssion for matching and replacing $key_equals_values_bracesRegExp = qr/ ( (?:$keyEqualsValuesBracesBracketsFollow) @@ -61,46 +64,54 @@ sub construct_key_equals_values_regexp{ (\R)? # $9 linebreak at end /sx; - $key_equals_values_bracesRegExpTrailingComment = qr/$key_equals_values_bracesRegExp(\h*)((?:$trailingCommentRegExp\h*)*)?/; + $key_equals_values_bracesRegExpTrailingComment + = qr/$key_equals_values_bracesRegExp(\h*)((?:$trailingCommentRegExp\h*)*)?/; } -sub indent_begin{ +sub indent_begin { my $self = shift; # blank line token my $blankLineToken = $tokens{blanklines}; - if(${$self}{begin} =~ /\R=/s or ${$self}{begin} =~ /$blankLineToken\h*=/s ){ + if ( ${$self}{begin} =~ /\R=/s or ${$self}{begin} =~ /$blankLineToken\h*=/s ) { $logger->trace("= found on own line in ${$self}{name}, adding indentation") if $is_t_switch_active; ${$self}{begin} =~ s/=/${$self}{indentation}=/s; } } -sub check_linebreaks_before_equals{ +sub check_linebreaks_before_equals { + # check if -m switch is active return unless $is_m_switch_active; - + my $self = shift; # linebreaks *infront* of = symbol - if(${$self}{begin} =~ /\R\h*=/s){ - if(defined ${$self}{EqualsStartsOnOwnLine} and ${$self}{EqualsStartsOnOwnLine}==-1){ - $logger->trace("Removing linebreak before = symbol in ${$self}{name} (see EqualsStartsOnOwnLine)") if $is_t_switch_active; + if ( ${$self}{begin} =~ /\R\h*=/s ) { + if ( defined ${$self}{EqualsStartsOnOwnLine} and ${$self}{EqualsStartsOnOwnLine} == -1 ) { + $logger->trace("Removing linebreak before = symbol in ${$self}{name} (see EqualsStartsOnOwnLine)") + if $is_t_switch_active; ${$self}{begin} =~ s/(\R|\h)*=/=/s; - } - } else { - if(defined ${$self}{EqualsStartsOnOwnLine} and ${$self}{EqualsStartsOnOwnLine}==1){ - $logger->trace("Adding a linebreak before = symbol for ${$self}{name} (see EqualsStartsOnOwnLine)") if $is_t_switch_active; + } + } + else { + if ( defined ${$self}{EqualsStartsOnOwnLine} and ${$self}{EqualsStartsOnOwnLine} == 1 ) { + $logger->trace("Adding a linebreak before = symbol for ${$self}{name} (see EqualsStartsOnOwnLine)") + if $is_t_switch_active; ${$self}{begin} =~ s/=/\n=/s; - } elsif(defined ${$self}{EqualsStartsOnOwnLine} and ${$self}{EqualsStartsOnOwnLine}==2){ - $logger->trace("Adding a % linebreak immediately before = symbol for ${$self}{name} (see EqualsStartsOnOwnLine)") if $is_t_switch_active; + } + elsif ( defined ${$self}{EqualsStartsOnOwnLine} and ${$self}{EqualsStartsOnOwnLine} == 2 ) { + $logger->trace( + "Adding a % linebreak immediately before = symbol for ${$self}{name} (see EqualsStartsOnOwnLine)") + if $is_t_switch_active; ${$self}{begin} =~ s/\h*=/%\n=/s; - } + } } return; } -sub create_unique_id{ +sub create_unique_id { my $self = shift; $key_equals_values_braces_Counter++; @@ -108,12 +119,12 @@ sub create_unique_id{ return; } -sub get_replacement_text{ +sub get_replacement_text { my $self = shift; - # the replacement text for a key = {value} needes to accomodate the leading [ OR { OR % OR , OR any combination thereof + # the replacement text for a key = {value} needes to accomodate the leading [ OR { OR % OR , OR any combination thereof $logger->trace("Custom replacement text routine for ${$self}{name}") if $is_t_switch_active; - ${$self}{replacementText} = ${$self}{beginningbit}.${$self}{id}; + ${$self}{replacementText} = ${$self}{beginningbit} . ${$self}{id}; delete ${$self}{beginningbit}; } diff --git a/Master/texmf-dist/scripts/latexindent/LatexIndent/Lines.pm b/Master/texmf-dist/scripts/latexindent/LatexIndent/Lines.pm index d1ee631b084..e2085b735df 100644 --- a/Master/texmf-dist/scripts/latexindent/LatexIndent/Lines.pm +++ b/Master/texmf-dist/scripts/latexindent/LatexIndent/Lines.pm @@ -1,4 +1,5 @@ package LatexIndent::Lines; + # 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 @@ -20,12 +21,12 @@ use Exporter qw/import/; use LatexIndent::LogFile qw/$logger/; use LatexIndent::Switches qw/%switches/; use LatexIndent::Verbatim qw/%verbatimStorage/; -our @ISA = "LatexIndent::Document"; # class inheritance, Programming Perl, pg 321 +our @ISA = "LatexIndent::Document"; # class inheritance, Programming Perl, pg 321 our @EXPORT_OK = qw/lines_body_selected_lines lines_verbatim_create_line_block/; sub lines_body_selected_lines { - my $self = shift; - my @lines = @{$_[0]}; + my $self = shift; + my @lines = @{ $_[0] }; # strip all space from lines switch $switches{lines} =~ s/\h//sg; @@ -33,11 +34,11 @@ sub lines_body_selected_lines { # convert multiple - into single $switches{lines} =~ s/-+/-/sg; - $logger->info("*-n,--lines switch is active, operating on lines $switches{lines}"); - $logger->info("number of lines in file: ".($#lines+1)); - $logger->info("*interpretting $switches{lines}"); - - my @lineRanges = split(/,/,$switches{lines}); + $logger->info("*-n,--lines switch is active, operating on lines $switches{lines}"); + $logger->info( "number of lines in file: " . ( $#lines + 1 ) ); + $logger->info("*interpretting $switches{lines}"); + + my @lineRanges = split( /,/, $switches{lines} ); my @indentLineRange; my @NOTindentLineRange; @@ -48,112 +49,119 @@ sub lines_body_selected_lines { # # --lines 3-15,17-19 # - foreach(@lineRanges){ - my $minLine = 0; - my $maxLine = 0; - my $negationMode = 0; - - # - # --lines !3-15 - # - if($_ =~ m/!/s){ - $negationMode = 1; - $_ =~ s/!//s; - $logger->info("negation mode active as $_"); - } - - # --lines min-max - if($_ =~ m/-/s){ - ($minLine,$maxLine) = split(/-/,$_); - } else { - $minLine = $_; - $maxLine = $_; - } - - # both minLine and maxLine need to be INTEGERS - if ($minLine !~ m/^\d+$/ or $maxLine !~ m/^\d+$/){ - $logger->warn("*$_ not a valid line specification; I'm ignoring this entry"); - next; - } - - # swap minLine and maxLine if necessary - if($minLine > $maxLine){ - ($minLine,$maxLine) = ($maxLine, $minLine); - } - - # minline > number of lines needs addressing - if ($minLine-1 > $#lines){ - $logger->warn("*--lines specified with min line $minLine which is *greater than* the number of lines in file: ".($#lines+1)); - $logger->warn("adjusting this value to be ".($#lines+1)); - $minLine = $#lines+1; - } - - # maxline > number of lines needs addressing - if ($maxLine-1 > $#lines){ - $logger->warn("*--lines specified with max line $maxLine which is *greater than* the number of lines in file: ".($#lines+1)); - $logger->warn("adjusting this value to be ".($#lines+1)); - $maxLine = $#lines+1; - } - - # either store the negation, or not - if($negationMode){ - $negationMinMaxStorage{$minLine} = $maxLine; - } else { - $minMaxStorage{$minLine} = $maxLine; - } - $logger->info("min line: $minLine, max line: $maxLine"); - } - + foreach (@lineRanges) { + my $minLine = 0; + my $maxLine = 0; + my $negationMode = 0; + + # + # --lines !3-15 + # + if ( $_ =~ m/!/s ) { + $negationMode = 1; + $_ =~ s/!//s; + $logger->info("negation mode active as $_"); + } + + # --lines min-max + if ( $_ =~ m/-/s ) { + ( $minLine, $maxLine ) = split( /-/, $_ ); + } + else { + $minLine = $_; + $maxLine = $_; + } + + # both minLine and maxLine need to be INTEGERS + if ( $minLine !~ m/^\d+$/ or $maxLine !~ m/^\d+$/ ) { + $logger->warn("*$_ not a valid line specification; I'm ignoring this entry"); + next; + } + + # swap minLine and maxLine if necessary + if ( $minLine > $maxLine ) { + ( $minLine, $maxLine ) = ( $maxLine, $minLine ); + } + + # minline > number of lines needs addressing + if ( $minLine - 1 > $#lines ) { + $logger->warn( + "*--lines specified with min line $minLine which is *greater than* the number of lines in file: " + . ( $#lines + 1 ) ); + $logger->warn( "adjusting this value to be " . ( $#lines + 1 ) ); + $minLine = $#lines + 1; + } + + # maxline > number of lines needs addressing + if ( $maxLine - 1 > $#lines ) { + $logger->warn( + "*--lines specified with max line $maxLine which is *greater than* the number of lines in file: " + . ( $#lines + 1 ) ); + $logger->warn( "adjusting this value to be " . ( $#lines + 1 ) ); + $maxLine = $#lines + 1; + } + + # either store the negation, or not + if ($negationMode) { + $negationMinMaxStorage{$minLine} = $maxLine; + } + else { + $minMaxStorage{$minLine} = $maxLine; + } + $logger->info("min line: $minLine, max line: $maxLine"); + } + # only proceed if we have a valid line range - if ( (keys %minMaxStorage) < 1 and (keys %negationMinMaxStorage) < 1){ - $logger->warn("*--lines not specified with valid range: $switches{lines}"); - $logger->warn("entire body will be indented, and ignoring $switches{lines}"); - $switches{lines} = 0; - ${$self}{body} = join("",@lines); - return; - } - + if ( ( keys %minMaxStorage ) < 1 and ( keys %negationMinMaxStorage ) < 1 ) { + $logger->warn("*--lines not specified with valid range: $switches{lines}"); + $logger->warn("entire body will be indented, and ignoring $switches{lines}"); + $switches{lines} = 0; + ${$self}{body} = join( "", @lines ); + return; + } + # we need to perform the token check here - ${$self}{body} = join("",@lines); + ${$self}{body} = join( "", @lines ); $self->token_check; ${$self}{body} = q(); # negated line ranges - if (keys %negationMinMaxStorage >= 1){ - @NOTindentLineRange = &lines_sort_and_combine_line_range(\%negationMinMaxStorage); + if ( keys %negationMinMaxStorage >= 1 ) { + @NOTindentLineRange = &lines_sort_and_combine_line_range( \%negationMinMaxStorage ); $logger->info("*negation line range summary: "); - $logger->info("the number of NEGATION line ranges: ".(($#NOTindentLineRange+1)/2)); + $logger->info( "the number of NEGATION line ranges: " . ( ( $#NOTindentLineRange + 1 ) / 2 ) ); $logger->info("the *sorted* NEGATION line ranges are in the form MIN-MAX: "); - for (my $index=0; $index<(($#NOTindentLineRange+1)/2); $index++){ - $logger->info(join("-",@NOTindentLineRange[2*$index..2*$index+1])); + for ( my $index = 0; $index < ( ( $#NOTindentLineRange + 1 ) / 2 ); $index++ ) { + $logger->info( join( "-", @NOTindentLineRange[ 2 * $index .. 2 * $index + 1 ] ) ); - if($index==0 and $NOTindentLineRange[2*$index]>1){ - $minMaxStorage{1} = $NOTindentLineRange[2*$index]-1; - } elsif($index>0){ - $minMaxStorage{$NOTindentLineRange[2*$index-1]+1} = $NOTindentLineRange[2*$index]-1; + if ( $index == 0 and $NOTindentLineRange[ 2 * $index ] > 1 ) { + $minMaxStorage{1} = $NOTindentLineRange[ 2 * $index ] - 1; + } + elsif ( $index > 0 ) { + $minMaxStorage{ $NOTindentLineRange[ 2 * $index - 1 ] + 1 } = $NOTindentLineRange[ 2 * $index ] - 1; } } # final range - if($NOTindentLineRange[-1]<$#lines){ - $minMaxStorage{$NOTindentLineRange[-1]+1} = $#lines+1; + if ( $NOTindentLineRange[-1] < $#lines ) { + $minMaxStorage{ $NOTindentLineRange[-1] + 1 } = $#lines + 1; } } - @indentLineRange = &lines_sort_and_combine_line_range(\%minMaxStorage) if (keys %minMaxStorage >= 1) ; + @indentLineRange = &lines_sort_and_combine_line_range( \%minMaxStorage ) if ( keys %minMaxStorage >= 1 ); $logger->info("*line range summary: "); - $logger->info("the number of indent line ranges: ".(($#indentLineRange+1)/2)); + $logger->info( "the number of indent line ranges: " . ( ( $#indentLineRange + 1 ) / 2 ) ); $logger->info("the *sorted* line ranges are in the form MIN-MAX: "); - for (my $index=0; $index<(($#indentLineRange+1)/2); $index++){ - $logger->info(join("-",@indentLineRange[2*$index..2*$index+1])); + for ( my $index = 0; $index < ( ( $#indentLineRange + 1 ) / 2 ); $index++ ) { + $logger->info( join( "-", @indentLineRange[ 2 * $index .. 2 * $index + 1 ] ) ); } my $startLine = 0; - # now that we have the line range, we can sort arrange the body - while ($#indentLineRange>0){ + # now that we have the line range, we can sort arrange the body + while ( $#indentLineRange > 0 ) { my $minLine = shift(@indentLineRange); my $maxLine = shift(@indentLineRange); @@ -161,72 +169,75 @@ sub lines_body_selected_lines { $minLine--; $maxLine--; - $self->lines_verbatim_create_line_block(\@lines,$startLine,$minLine-1) unless ($minLine == 0); + $self->lines_verbatim_create_line_block( \@lines, $startLine, $minLine - 1 ) unless ( $minLine == 0 ); - ${$self}{body} .= join("",@lines[$minLine..$maxLine]); + ${$self}{body} .= join( "", @lines[ $minLine .. $maxLine ] ); - $startLine = $maxLine+1; + $startLine = $maxLine + 1; } # final line range - $self->lines_verbatim_create_line_block(\@lines,$startLine,$#lines) if($startLine<=$#lines); + $self->lines_verbatim_create_line_block( \@lines, $startLine, $#lines ) if ( $startLine <= $#lines ); return; } -sub lines_sort_and_combine_line_range{ +sub lines_sort_and_combine_line_range { - my %minMaxStorage = %{$_[0]}; + my %minMaxStorage = %{ $_[0] }; # # --lines 8-10,4-5,1-2 # - # needs to be interpretted as + # needs to be interpretted as # - # --lines 1-2,4-5,8-10, + # --lines 1-2,4-5,8-10, # - # sort the line ranges by the *minimum* value, the associated + # sort the line ranges by the *minimum* value, the associated # maximum values will be arranged after this my @indentLineRange = sort { $a <=> $b } keys(%minMaxStorage); - my @justMinimumValues = @indentLineRange; - for (my $index=0;$index<=$#justMinimumValues;$index++){ - splice(@indentLineRange,2*$index+1,0,$minMaxStorage{$justMinimumValues[$index]}); + my @justMinimumValues = @indentLineRange; + for ( my $index = 0; $index <= $#justMinimumValues; $index++ ) { + splice( @indentLineRange, 2 * $index + 1, 0, $minMaxStorage{ $justMinimumValues[$index] } ); } - for (my $index=1;$index<(($#indentLineRange+1)/2);$index++){ - my $currentMin = $indentLineRange[2*$index]; - my $currentMax = $indentLineRange[2*$index+1]; - my $previousMax = $indentLineRange[2*$index-1]; - my $previousMin = $indentLineRange[2*$index-2]; + for ( my $index = 1; $index < ( ( $#indentLineRange + 1 ) / 2 ); $index++ ) { + my $currentMin = $indentLineRange[ 2 * $index ]; + my $currentMax = $indentLineRange[ 2 * $index + 1 ]; + my $previousMax = $indentLineRange[ 2 * $index - 1 ]; + my $previousMin = $indentLineRange[ 2 * $index - 2 ]; + + if ( ( $currentMin - 1 ) <= $previousMax and ( $currentMax > $previousMax ) ) { - if ( ($currentMin - 1) <= $previousMax and ( $currentMax > $previousMax ) ){ # overlapping line ranges, for example # - # --lines 3-5,4-10 + # --lines 3-5,4-10 # - # needs to be interpretted as + # needs to be interpretted as # - # --lines 3-10 + # --lines 3-10 # $logger->info("overlapping line range found"); - $logger->info("line ranges (before): ".join(", ",@indentLineRange)); - splice(@indentLineRange,2*$index-1,2); - $logger->info("line ranges (after): ".join(", ",@indentLineRange)); + $logger->info( "line ranges (before): " . join( ", ", @indentLineRange ) ); + splice( @indentLineRange, 2 * $index - 1, 2 ); + $logger->info( "line ranges (after): " . join( ", ", @indentLineRange ) ); # reset index so that loop starts again $index = 0; - } elsif ( ($currentMin - 1) <= $previousMax and ( $currentMax <= $previousMax ) ){ + } + elsif ( ( $currentMin - 1 ) <= $previousMax and ( $currentMax <= $previousMax ) ) { + # overlapping line ranges, for example # # --lines 3-7,4-6 # - # needs to be interpretted as + # needs to be interpretted as # # --lines 3-7 # $logger->info("overlapping line range found"); - $logger->info("line ranges (before): ".join(", ",@indentLineRange)); - splice(@indentLineRange,2*$index,2); - $logger->info("line ranges (after): ".join(", ",@indentLineRange)); + $logger->info( "line ranges (before): " . join( ", ", @indentLineRange ) ); + splice( @indentLineRange, 2 * $index, 2 ); + $logger->info( "line ranges (after): " . join( ", ", @indentLineRange ) ); # reset index so that loop starts again $index = 0; @@ -236,32 +247,33 @@ sub lines_sort_and_combine_line_range{ return @indentLineRange; } -sub lines_verbatim_create_line_block{ - my $self = shift; - my @lines = @{$_[0]}; - my $startLine = $_[1]; +sub lines_verbatim_create_line_block { + my $self = shift; + my @lines = @{ $_[0] }; + my $startLine = $_[1]; my $finishLine = $_[2]; - my $verbBody = join("",@lines[$startLine..$finishLine]); + my $verbBody = join( "", @lines[ $startLine .. $finishLine ] ); $verbBody =~ s/\R?$//s; # create a new Verbatim object - my $noIndentBlockObj = LatexIndent::Verbatim->new( begin=>q(), - body=>$verbBody, - end=>q(), - name=>"line-switch-verbatim-protection", - type=>"linesprotect", - modifyLineBreaksYamlName=>"lines-not-to-be-indented", - ); - + my $noIndentBlockObj = LatexIndent::Verbatim->new( + begin => q(), + body => $verbBody, + end => q(), + name => "line-switch-verbatim-protection", + type => "linesprotect", + modifyLineBreaksYamlName => "lines-not-to-be-indented", + ); + # give unique id $noIndentBlockObj->create_unique_id; # verbatim children go in special hash - $verbatimStorage{${$noIndentBlockObj}{id}}=$noIndentBlockObj; + $verbatimStorage{ ${$noIndentBlockObj}{id} } = $noIndentBlockObj; # remove the environment block, and replace with unique ID - ${$self}{body} .= ${$noIndentBlockObj}{id}."\n"; + ${$self}{body} .= ${$noIndentBlockObj}{id} . "\n"; return; } diff --git a/Master/texmf-dist/scripts/latexindent/LatexIndent/LogFile.pm b/Master/texmf-dist/scripts/latexindent/LatexIndent/LogFile.pm index fa6df78828f..cd6ec912c3b 100644 --- a/Master/texmf-dist/scripts/latexindent/LatexIndent/LogFile.pm +++ b/Master/texmf-dist/scripts/latexindent/LatexIndent/LogFile.pm @@ -1,4 +1,5 @@ package LatexIndent::LogFile; + # 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 @@ -16,25 +17,29 @@ package LatexIndent::LogFile; # For all communication, please visit: https://github.com/cmhughes/latexindent.pl use strict; use warnings; -use FindBin; -use File::Basename; # to get the filename and directory path +use FindBin; +use File::Basename; # to get the filename and directory path use Exporter qw/import/; use LatexIndent::Switches qw/%switches/; use LatexIndent::Version qw/$versionNumber $versionDate/; our @EXPORT_OK = qw/process_switches $logger/; our $logger; -sub process_switches{ +sub process_switches { + # -v switch is just to show the version number - if($switches{version}) { - print $versionNumber,", ",$versionDate,"\n"; - if ($switches{vversion}) { + if ( $switches{version} ) { + print $versionNumber, ", ", $versionDate, "\n"; + if ( $switches{vversion} ) { print "$FindBin::Script lives here: $FindBin::RealBin/$FindBin::Script\n"; - if ( -e "$FindBin::RealBin/defaultSettings.yaml" ){ + if ( -e "$FindBin::RealBin/defaultSettings.yaml" ) { print "defaultSettings.yaml lives here $FindBin::RealBin/defaultSettings.yaml\n"; - } elsif ( -e "$FindBin::RealBin/../../texmf-dist/scripts/latexindent/defaultSettings.yaml" ){ - print "defaultSettings.yaml lives here $FindBin::RealBin/../../texmf-dist/scripts/latexindent/defaultSettings.yaml\n"; - } elsif ( -e "$FindBin::RealBin/LatexIndent/defaultSettings.yaml" ) { + } + elsif ( -e "$FindBin::RealBin/../../texmf-dist/scripts/latexindent/defaultSettings.yaml" ) { + print + "defaultSettings.yaml lives here $FindBin::RealBin/../../texmf-dist/scripts/latexindent/defaultSettings.yaml\n"; + } + elsif ( -e "$FindBin::RealBin/LatexIndent/defaultSettings.yaml" ) { print "defaultSettings.yaml lives here $FindBin::RealBin/LatexIndent/defaultSettings.yaml\n"; } print "project home: https://github.com/cmhughes/latexindent.pl\n"; @@ -42,8 +47,8 @@ sub process_switches{ exit(0); } - if(scalar(@ARGV) < 1 or $switches{showhelp}) { - print <<ENDQUOTE + if ( scalar(@ARGV) < 1 or $switches{showhelp} ) { + print <<ENDQUOTE latexindent.pl version $versionNumber, $versionDate usage: latexindent.pl [options] [file] -v, --version @@ -110,29 +115,30 @@ usage: latexindent.pl [options] [file] loads the Unicode::GCString module for the align-at-ampersand routine Note: this requires the Unicode::GCString module to be installed on your system ENDQUOTE - ; - exit(0); -} + ; + exit(0); + } # if we've made it this far, the processing of switches and logging begins - my $self = shift; - my @fileNames = @{$_[0]}; + my $self = shift; + my @fileNames = @{ $_[0] }; $logger = LatexIndent::Logger->new(); - + # cruft directory - ${$self}{cruftDirectory} = $switches{cruftDirectory}||(dirname ${$self}{fileName}); + ${$self}{cruftDirectory} = $switches{cruftDirectory} || ( dirname ${$self}{fileName} ); # if cruft directory does not exist - if(!(-d ${$self}{cruftDirectory})){ + if ( !( -d ${$self}{cruftDirectory} ) ) { $logger->fatal("*Could not find directory ${$self}{cruftDirectory}"); - $logger->fatal("Exiting, no indendation done."); + $logger->fatal("Exiting, no indendation done."); $self->output_logfile(); exit(6); } - my $logfileName = ($switches{cruftDirectory} ? ${$self}{cruftDirectory}."/" : '').($switches{logFileName}||"indent.log"); - + my $logfileName = ( $switches{cruftDirectory} ? ${$self}{cruftDirectory} . "/" : '' ) + . ( $switches{logFileName} || "indent.log" ); + # details of the script to log file $logger->info("*$FindBin::Script version $versionNumber, $versionDate, a script to indent .tex files"); $logger->info("$FindBin::Script lives here: $FindBin::RealBin/"); @@ -140,21 +146,24 @@ ENDQUOTE my $time = localtime(); $logger->info($time); - if (${$self}{fileName} ne "-"){ + if ( ${$self}{fileName} ne "-" ) { + # multiple filenames or not - if ( (scalar (@fileNames)) >1 ){ - $logger->info("Filenames:"); - foreach (@fileNames) { - $logger->info(" $_"); - } - $logger->info("total number of files: ".(scalar (@fileNames))); - } else { - $logger->info("Filename: ${$self}{fileName}"); + if ( ( scalar(@fileNames) ) > 1 ) { + $logger->info("Filenames:"); + foreach (@fileNames) { + $logger->info(" $_"); + } + $logger->info( "total number of files: " . ( scalar(@fileNames) ) ); + } + else { + $logger->info("Filename: ${$self}{fileName}"); } - } else { + } + else { $logger->info("Reading input from STDIN"); - if (-t STDIN) { - my $buttonText = ($FindBin::Script eq 'latexindent.exe') ? 'CTRL+Z followed by ENTER':'CTRL+D'; + if ( -t STDIN ) { + my $buttonText = ( $FindBin::Script eq 'latexindent.exe' ) ? 'CTRL+Z followed by ENTER' : 'CTRL+D'; print STDERR "Please enter text to be indented: (press $buttonText when finished)\n"; } } @@ -163,51 +172,56 @@ ENDQUOTE $logger->info("*Processing switches:"); # check on the trace mode switch (should be turned on if ttrace mode active) - $switches{trace} = $switches{ttrace} ? 1 : $switches{trace}; - + $switches{trace} = $switches{ttrace} ? 1 : $switches{trace}; + # output details of switches - $logger->info("-sl|--screenlog: log file will also be output to the screen") if($switches{screenlog}); - $logger->info("-t|--trace: Trace mode active (you have used either -t or --trace)") if($switches{trace} and !$switches{ttrace}); - $logger->info("-tt|--ttrace: TTrace mode active (you have used either -tt or --ttrace)") if($switches{ttrace}); - $logger->info("-s|--silent: Silent mode active (you have used either -s or --silent)") if($switches{silentMode}); - $logger->info("-d|--onlydefault: Only defaultSettings.yaml will be used (you have used either -d or --onlydefault)") if($switches{onlyDefault}); - $logger->info("-w|--overwrite: Overwrite mode active, will make a back up before overwriting") if($switches{overwrite}); - $logger->info("-wd|--overwriteIfDifferent: will overwrite ONLY if indented text is different") if($switches{overwriteIfDifferent}); - $logger->info("-l|--localSettings: Read localSettings YAML file") if($switches{readLocalSettings}); - $logger->info("-y|--yaml: YAML settings specified via command line") if($switches{yaml}); - $logger->info("-o|--outputfile: output to file") if($switches{outputToFile}); - $logger->info("-m|--modifylinebreaks: modify line breaks") if($switches{modifyLineBreaks}); - $logger->info("-g|--logfile: logfile name") if($switches{logFileName}); - $logger->info("-c|--cruft: cruft directory") if($switches{cruftDirectory}); - $logger->info("-r|--replacement: replacement mode") if($switches{replacement}); - $logger->info("-rr|--onlyreplacement: *only* replacement mode, no indentation") if($switches{onlyreplacement}); - $logger->info("-k|--check mode: will exit with 0 if document body unchanged, 1 if changed") if($switches{check}); - $logger->info("-kv|--check mode verbose: as in check mode, but outputs diff to screen") if($switches{checkverbose}); - $logger->info("-n|--lines mode: will only operate on specific lines $switches{lines}") if($switches{lines}); - $logger->info("--GCString switch active, loading Unicode::GCString module") if($switches{GCString}); + $logger->info("-sl|--screenlog: log file will also be output to the screen") if ( $switches{screenlog} ); + $logger->info("-t|--trace: Trace mode active (you have used either -t or --trace)") + if ( $switches{trace} and !$switches{ttrace} ); + $logger->info("-tt|--ttrace: TTrace mode active (you have used either -tt or --ttrace)") if ( $switches{ttrace} ); + $logger->info("-s|--silent: Silent mode active (you have used either -s or --silent)") if ( $switches{silentMode} ); + $logger->info("-d|--onlydefault: Only defaultSettings.yaml will be used (you have used either -d or --onlydefault)") + if ( $switches{onlyDefault} ); + $logger->info("-w|--overwrite: Overwrite mode active, will make a back up before overwriting") + if ( $switches{overwrite} ); + $logger->info("-wd|--overwriteIfDifferent: will overwrite ONLY if indented text is different") + if ( $switches{overwriteIfDifferent} ); + $logger->info("-l|--localSettings: Read localSettings YAML file") if ( $switches{readLocalSettings} ); + $logger->info("-y|--yaml: YAML settings specified via command line") if ( $switches{yaml} ); + $logger->info("-o|--outputfile: output to file") if ( $switches{outputToFile} ); + $logger->info("-m|--modifylinebreaks: modify line breaks") if ( $switches{modifyLineBreaks} ); + $logger->info("-g|--logfile: logfile name") if ( $switches{logFileName} ); + $logger->info("-c|--cruft: cruft directory") if ( $switches{cruftDirectory} ); + $logger->info("-r|--replacement: replacement mode") if ( $switches{replacement} ); + $logger->info("-rr|--onlyreplacement: *only* replacement mode, no indentation") if ( $switches{onlyreplacement} ); + $logger->info("-k|--check mode: will exit with 0 if document body unchanged, 1 if changed") if ( $switches{check} ); + $logger->info("-kv|--check mode verbose: as in check mode, but outputs diff to screen") + if ( $switches{checkverbose} ); + $logger->info("-n|--lines mode: will only operate on specific lines $switches{lines}") if ( $switches{lines} ); + $logger->info("--GCString switch active, loading Unicode::GCString module") if ( $switches{GCString} ); # check if overwrite and outputfile are active similtaneously - if($switches{overwrite} and $switches{outputToFile}){ + if ( $switches{overwrite} and $switches{outputToFile} ) { $logger->info("*Options check: -w and -o specified"); $logger->info("You have called latexindent.pl with both -o and -w"); $logger->info("The -o switch will take priority, and -w (overwrite) will be ignored"); - $switches{overwrite}=0; + $switches{overwrite} = 0; } # check if overwrite and outputfile are active similtaneously - if($switches{overwrite} and $switches{overwriteIfDifferent}){ + if ( $switches{overwrite} and $switches{overwriteIfDifferent} ) { $logger->info("*Options check: -w and -wd specified"); $logger->info("You have called latexindent.pl with both -w and -wd."); $logger->info("The -wd switch will take priority, and -w (overwrite) will be ignored"); - $switches{overwrite}=0; + $switches{overwrite} = 0; } # check if overwriteIfDifferent and outputfile are active similtaneously - if($switches{overwriteIfDifferent} and $switches{outputToFile}){ + if ( $switches{overwriteIfDifferent} and $switches{outputToFile} ) { $logger->info("*Options check: -wd and -o specified"); $logger->info("You have called latexindent.pl with both -o and -wd"); $logger->info("The -o switch will take priority, and -wd (overwriteIfDifferent) will be ignored"); - $switches{overwriteIfDifferent}=0; + $switches{overwriteIfDifferent} = 0; } # multiple files with the -o switch needs care @@ -218,32 +232,33 @@ ENDQUOTE # # would result in only the final file being written to myfile.tex # - # So, if -o switch does *not* match having a + symbol at the beginning, then + # So, if -o switch does *not* match having a + symbol at the beginning, then # we ignore it, and turn it off # - if ( (scalar @fileNames>1) and $switches{outputToFile} and ($switches{outputToFile} !~ m/^h*\+/) ){ + if ( ( scalar @fileNames > 1 ) and $switches{outputToFile} and ( $switches{outputToFile} !~ m/^h*\+/ ) ) { $logger->warn("*-o switch specified as single file, but multiple files given as input"); $logger->warn("ignoring your specification -o $switches{outputToFile}"); $logger->warn("perhaps you migh specify it using, for example, -o=++ or -o=+myoutput"); - $switches{outputToFile} =0; + $switches{outputToFile} = 0; } $logger->info("*Directory for backup files and $logfileName:"); $logger->info("${$self}{cruftDirectory}"); # output location of modules - if($FindBin::Script eq 'latexindent.pl' or ($FindBin::Script eq 'latexindent.exe' and $switches{trace} )) { - my @listOfModules = ('FindBin', 'YAML::Tiny', 'File::Copy', 'File::Basename', 'Getopt::Long','File::HomeDir'); - push(@listOfModules,'Unicode::GCString') if $switches{GCString}; + if ( $FindBin::Script eq 'latexindent.pl' or ( $FindBin::Script eq 'latexindent.exe' and $switches{trace} ) ) { + my @listOfModules + = ( 'FindBin', 'YAML::Tiny', 'File::Copy', 'File::Basename', 'Getopt::Long', 'File::HomeDir' ); + push( @listOfModules, 'Unicode::GCString' ) if $switches{GCString}; $logger->info("*Perl modules are being loaded from the following directories:"); foreach my $moduleName (@listOfModules) { - (my $file = $moduleName) =~ s|::|/|g; - $logger->info($INC{$file .'.pm'}); - } + ( my $file = $moduleName ) =~ s|::|/|g; + $logger->info( $INC{ $file . '.pm' } ); + } $logger->info("*LatexIndent perl modules are being loaded from, for example:"); - (my $file = 'LatexIndent::Document') =~ s|::|/|g; - $logger->info($INC{$file .'.pm'}); + ( my $file = 'LatexIndent::Document' ) =~ s|::|/|g; + $logger->info( $INC{ $file . '.pm' } ); } return; diff --git a/Master/texmf-dist/scripts/latexindent/LatexIndent/Logger.pm b/Master/texmf-dist/scripts/latexindent/LatexIndent/Logger.pm index ebad76a2d51..425c8eae07f 100644 --- a/Master/texmf-dist/scripts/latexindent/LatexIndent/Logger.pm +++ b/Master/texmf-dist/scripts/latexindent/LatexIndent/Logger.pm @@ -1,4 +1,5 @@ package LatexIndent::Logger; + # 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 @@ -19,61 +20,65 @@ use strict; use warnings; use Exporter; use LatexIndent::Switches qw/%switches/; -our @ISA = "LatexIndent::Document"; # class inheritance, Programming Perl, pg 321 +our @ISA = "LatexIndent::Document"; # class inheritance, Programming Perl, pg 321 our @EXPORT_OK = qw/@logFileLines/; our @logFileLines; -sub info{ - my $self = shift; +sub info { + my $self = shift; my $logfileline = shift; - return unless (defined $logfileline); - if ($logfileline =~ m/^\*/s){ + return unless ( defined $logfileline ); + if ( $logfileline =~ m/^\*/s ) { $logfileline =~ s/^\*/INFO: /s; $logfileline =~ s/^/ /mg; $logfileline =~ s/^\h+INFO/INFO/s; - } else { + } + else { $logfileline =~ s/^/ /mg; } - push(@logFileLines,$logfileline); - print $logfileline,"\n" if $switches{screenlog}; + push( @logFileLines, $logfileline ); + print $logfileline, "\n" if $switches{screenlog}; } -sub warn{ - my $self = shift; +sub warn { + my $self = shift; my $logfileline = shift; - if ($logfileline =~ m/^\*/s){ - $logfileline =~ s/^\*/WARN: /s - } else { + if ( $logfileline =~ m/^\*/s ) { + $logfileline =~ s/^\*/WARN: /s; + } + else { $logfileline =~ s/^/ /mg; } - push(@logFileLines,$logfileline); - print $logfileline,"\n" if $switches{screenlog}; + push( @logFileLines, $logfileline ); + print $logfileline, "\n" if $switches{screenlog}; } -sub fatal{ - my $self = shift; +sub fatal { + my $self = shift; my $logfileline = shift; - if ($logfileline =~ m/^\*/s){ + if ( $logfileline =~ m/^\*/s ) { $logfileline =~ s/^\*/FATAL /s; $logfileline =~ s/^/ /mg; $logfileline =~ s/^\h+FATAL/FATAL/s; - } else { + } + else { $logfileline =~ s/^/ /mg; } - push(@logFileLines,$logfileline); - print $logfileline,"\n"; + push( @logFileLines, $logfileline ); + print $logfileline, "\n"; } -sub trace{ - my $self = shift; +sub trace { + my $self = shift; my $logfileline = shift; - if ($logfileline =~ m/^\*/s){ - $logfileline =~ s/^\*/TRACE: /s - } else { + if ( $logfileline =~ m/^\*/s ) { + $logfileline =~ s/^\*/TRACE: /s; + } + else { $logfileline =~ s/^/ /mg; } - push(@logFileLines,$logfileline); - print $logfileline,"\n" if $switches{screenlog}; + push( @logFileLines, $logfileline ); + print $logfileline, "\n" if $switches{screenlog}; } 1; diff --git a/Master/texmf-dist/scripts/latexindent/LatexIndent/MandatoryArgument.pm b/Master/texmf-dist/scripts/latexindent/LatexIndent/MandatoryArgument.pm index a7b4e2088ae..65982ba7b57 100644 --- a/Master/texmf-dist/scripts/latexindent/LatexIndent/MandatoryArgument.pm +++ b/Master/texmf-dist/scripts/latexindent/LatexIndent/MandatoryArgument.pm @@ -1,4 +1,5 @@ package LatexIndent::MandatoryArgument; + # 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 @@ -23,20 +24,21 @@ use LatexIndent::LogFile qw/$logger/; use LatexIndent::IfElseFi qw/$ifElseFiBasicRegExp/; use LatexIndent::Special qw/$specialBeginBasicRegExp/; use Exporter qw/import/; -our @ISA = "LatexIndent::Document"; # class inheritance, Programming Perl, pg 321 +our @ISA = "LatexIndent::Document"; # class inheritance, Programming Perl, pg 321 our @EXPORT_OK = qw/find_mandatory_arguments get_mand_arg_reg_exp/; our $mandatoryArgumentCounter; -sub find_mandatory_arguments{ +sub find_mandatory_arguments { my $self = shift; my $mandArgRegExp = $self->get_mand_arg_reg_exp; # pick out the mandatory arguments - while(${$self}{body} =~ m/$mandArgRegExp\h*($trailingCommentRegExp)*(.*)/s){ + while ( ${$self}{body} =~ m/$mandArgRegExp\h*($trailingCommentRegExp)*(.*)/s ) { + # log file output $logger->trace("*Mandatory argument found, body in ${$self}{name}") if $is_t_switch_active; - $logger->trace("(last argument)") if($9 eq '' and $is_t_switch_active); + $logger->trace("(last argument)") if ( $9 eq '' and $is_t_switch_active ); ${$self}{body} =~ s/ $mandArgRegExp(\h*)($trailingCommentRegExp)*(.*) @@ -73,11 +75,11 @@ sub find_mandatory_arguments{ $self->get_settings_and_store_new_object($mandatoryArg); ${@{${$self}{children}}[-1]}{replacementText}.($8?$8:q()).($9?$9:q()).($10?$10:q()); /xseg; - $self->wrap_up_tasks; - } - } + $self->wrap_up_tasks; + } +} -sub create_unique_id{ +sub create_unique_id { my $self = shift; $mandatoryArgumentCounter++; @@ -85,7 +87,7 @@ sub create_unique_id{ return; } -sub get_mand_arg_reg_exp{ +sub get_mand_arg_reg_exp { my $mandArgRegExp = qr/ (?<!\\) # not immediately pre-ceeded by \ @@ -113,21 +115,23 @@ sub get_mand_arg_reg_exp{ return $mandArgRegExp; } -sub yaml_get_object_attribute_for_indentation_settings{ +sub yaml_get_object_attribute_for_indentation_settings { my $self = shift; - + return ${$self}{modifyLineBreaksYamlName}; } -sub tasks_particular_to_each_object{ +sub tasks_particular_to_each_object { my $self = shift; # lookForAlignDelims: lookForChildCodeBlocks set to 0 means no child objects searched for # see: test-cases/alignment/issue-308-command.tex # - if( defined ${$self}{lookForChildCodeBlocks} and !${$self}{lookForChildCodeBlocks} ){ - $logger->trace("lookForAlignDelims: lookForChildCodeBlocks set to 0, so child objects will *NOT* be searched for") if($is_t_switch_active); - return; + if ( defined ${$self}{lookForChildCodeBlocks} and !${$self}{lookForChildCodeBlocks} ) { + $logger->trace( + "lookForAlignDelims: lookForChildCodeBlocks set to 0, so child objects will *NOT* be searched for") + if ($is_t_switch_active); + return; } # search for ifElseFi blocks diff --git a/Master/texmf-dist/scripts/latexindent/LatexIndent/ModifyLineBreaks.pm b/Master/texmf-dist/scripts/latexindent/LatexIndent/ModifyLineBreaks.pm index 4d3356183b2..5d3a915f618 100644 --- a/Master/texmf-dist/scripts/latexindent/LatexIndent/ModifyLineBreaks.pm +++ b/Master/texmf-dist/scripts/latexindent/LatexIndent/ModifyLineBreaks.pm @@ -1,4 +1,5 @@ package LatexIndent::ModifyLineBreaks; + # 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 @@ -24,79 +25,101 @@ use LatexIndent::Switches qw/$is_m_switch_active $is_t_switch_active $is_tt_swit use LatexIndent::Item qw/$listOfItems/; use LatexIndent::LogFile qw/$logger/; use LatexIndent::Verbatim qw/%verbatimStorage/; -our @EXPORT_OK = qw/modify_line_breaks_body modify_line_breaks_end modify_line_breaks_end_after adjust_line_breaks_end_parent remove_line_breaks_begin verbatim_modify_line_breaks/; +our @EXPORT_OK + = qw/modify_line_breaks_body modify_line_breaks_end modify_line_breaks_end_after adjust_line_breaks_end_parent remove_line_breaks_begin verbatim_modify_line_breaks/; our $paragraphRegExp = q(); -sub modify_line_breaks_body{ +sub modify_line_breaks_body { my $self = shift; - # + # # Blank line poly-switch notes (==4) # # when BodyStartsOnOwnLine=4 we adopt the following approach: # temporarily change BodyStartsOnOwnLine to -1, make adjustments # temporarily change BodyStartsOnOwnLine to 3, make adjustments # switch BodyStartsOnOwnLine back to 4 - + # add a line break after \begin{statement} if appropriate - my @polySwitchValues = (${$self}{BodyStartsOnOwnLine}==4)?(-1,3):(${$self}{BodyStartsOnOwnLine}); - foreach(@polySwitchValues){ - my $BodyStringLogFile = ${$self}{aliases}{BodyStartsOnOwnLine}||"BodyStartsOnOwnLine"; - if($_>=1 and !${$self}{linebreaksAtEnd}{begin}){ - # if the <begin> statement doesn't finish with a line break, - # then we have different actions based upon the value of BodyStartsOnOwnLine: - # BodyStartsOnOwnLine == 1 just add a new line - # BodyStartsOnOwnLine == 2 add a comment, and then new line - # BodyStartsOnOwnLine == 3 add a blank line, and then new line - if($_==1){ - # modify the begin statement - $logger->trace("Adding a linebreak at the end of begin statement ${$self}{begin} (see $BodyStringLogFile)") if $is_t_switch_active; - ${$self}{begin} .= "\n"; - ${$self}{linebreaksAtEnd}{begin} = 1; - $logger->trace("Removing leading space from body of ${$self}{name} (see $BodyStringLogFile)") if $is_t_switch_active; - ${$self}{body} =~ s/^\h*//; - } elsif($_==2){ - # by default, assume that no trailing comment token is needed - my $trailingCommentToken = q(); - if(${$self}{body} !~ m/^\h*$trailingCommentRegExp/s){ + my @polySwitchValues = ( ${$self}{BodyStartsOnOwnLine} == 4 ) ? ( -1, 3 ) : ( ${$self}{BodyStartsOnOwnLine} ); + foreach (@polySwitchValues) { + my $BodyStringLogFile = ${$self}{aliases}{BodyStartsOnOwnLine} || "BodyStartsOnOwnLine"; + if ( $_ >= 1 and !${$self}{linebreaksAtEnd}{begin} ) { + + # if the <begin> statement doesn't finish with a line break, + # then we have different actions based upon the value of BodyStartsOnOwnLine: + # BodyStartsOnOwnLine == 1 just add a new line + # BodyStartsOnOwnLine == 2 add a comment, and then new line + # BodyStartsOnOwnLine == 3 add a blank line, and then new line + if ( $_ == 1 ) { + # modify the begin statement - $logger->trace("Adding a % at the end of begin ${$self}{begin} followed by a linebreak ($BodyStringLogFile == 2)") if $is_t_switch_active; - $trailingCommentToken = "%".$self->add_comment_symbol; - ${$self}{begin} =~ s/\h*$//; - ${$self}{begin} .= "$trailingCommentToken\n"; + $logger->trace( + "Adding a linebreak at the end of begin statement ${$self}{begin} (see $BodyStringLogFile)") + if $is_t_switch_active; + ${$self}{begin} .= "\n"; ${$self}{linebreaksAtEnd}{begin} = 1; - $logger->trace("Removing leading space from body of ${$self}{name} (see $BodyStringLogFile)") if $is_t_switch_active; - ${$self}{body} =~ s/^\h*//; - } else { - $logger->trace("Even though $BodyStringLogFile == 2, ${$self}{begin} already finishes with a %, so not adding another.") if $is_t_switch_active; + $logger->trace("Removing leading space from body of ${$self}{name} (see $BodyStringLogFile)") + if $is_t_switch_active; + ${$self}{body} =~ s/^\h*//; } - } elsif ($_==3){ - my $trailingCharacterToken = q(); - $logger->trace("Adding a blank line at the end of begin ${$self}{begin} followed by a linebreak ($BodyStringLogFile == 3)") if $is_t_switch_active; - ${$self}{begin} =~ s/\h*$//; - ${$self}{begin} .= (${$mainSettings{modifyLineBreaks}}{preserveBlankLines}?$tokens{blanklines}:"\n")."\n"; - ${$self}{linebreaksAtEnd}{begin} = 1; - $logger->trace("Removing leading space from body of ${$self}{name} (see $BodyStringLogFile)") if $is_t_switch_active; - ${$self}{body} =~ s/^\h*//; - } - } elsif ($_==-1 and ${$self}{linebreaksAtEnd}{begin}){ - # remove line break *after* begin, if appropriate - $self->remove_line_breaks_begin; - } + elsif ( $_ == 2 ) { + + # by default, assume that no trailing comment token is needed + my $trailingCommentToken = q(); + if ( ${$self}{body} !~ m/^\h*$trailingCommentRegExp/s ) { + + # modify the begin statement + $logger->trace( + "Adding a % at the end of begin ${$self}{begin} followed by a linebreak ($BodyStringLogFile == 2)" + ) if $is_t_switch_active; + $trailingCommentToken = "%" . $self->add_comment_symbol; + ${$self}{begin} =~ s/\h*$//; + ${$self}{begin} .= "$trailingCommentToken\n"; + ${$self}{linebreaksAtEnd}{begin} = 1; + $logger->trace("Removing leading space from body of ${$self}{name} (see $BodyStringLogFile)") + if $is_t_switch_active; + ${$self}{body} =~ s/^\h*//; + } + else { + $logger->trace( + "Even though $BodyStringLogFile == 2, ${$self}{begin} already finishes with a %, so not adding another." + ) if $is_t_switch_active; + } + } + elsif ( $_ == 3 ) { + my $trailingCharacterToken = q(); + $logger->trace( + "Adding a blank line at the end of begin ${$self}{begin} followed by a linebreak ($BodyStringLogFile == 3)" + ) if $is_t_switch_active; + ${$self}{begin} =~ s/\h*$//; + ${$self}{begin} + .= ( ${ $mainSettings{modifyLineBreaks} }{preserveBlankLines} ? $tokens{blanklines} : "\n" ) . "\n"; + ${$self}{linebreaksAtEnd}{begin} = 1; + $logger->trace("Removing leading space from body of ${$self}{name} (see $BodyStringLogFile)") + if $is_t_switch_active; + ${$self}{body} =~ s/^\h*//; + } + } + elsif ( $_ == -1 and ${$self}{linebreaksAtEnd}{begin} ) { + + # remove line break *after* begin, if appropriate + $self->remove_line_breaks_begin; + } } } -sub remove_line_breaks_begin{ - my $self = shift; - my $BodyStringLogFile = ${$self}{aliases}{BodyStartsOnOwnLine}||"BodyStartsOnOwnLine"; +sub remove_line_breaks_begin { + my $self = shift; + my $BodyStringLogFile = ${$self}{aliases}{BodyStartsOnOwnLine} || "BodyStartsOnOwnLine"; $logger->trace("Removing linebreak at the end of begin (see $BodyStringLogFile)") if $is_t_switch_active; ${$self}{begin} =~ s/\R*$//sx; ${$self}{linebreaksAtEnd}{begin} = 0; } -sub modify_line_breaks_end{ +sub modify_line_breaks_end { my $self = shift; - # + # # Blank line poly-switch notes (==4) # # when EndStartsOnOwnLine=4 we adopt the following approach: @@ -104,60 +127,77 @@ sub modify_line_breaks_end{ # temporarily change EndStartsOnOwnLine to 3, make adjustments # switch EndStartsOnOwnLine back to 4 # - - my @polySwitchValues =(${$self}{EndStartsOnOwnLine}==4) ?(-1,3):(${$self}{EndStartsOnOwnLine}); - foreach(@polySwitchValues){ + + my @polySwitchValues = ( ${$self}{EndStartsOnOwnLine} == 4 ) ? ( -1, 3 ) : ( ${$self}{EndStartsOnOwnLine} ); + foreach (@polySwitchValues) { + # possibly modify line break *before* \end{statement} - if(defined ${$self}{EndStartsOnOwnLine}){ - my $EndStringLogFile = ${$self}{aliases}{EndStartsOnOwnLine}||"EndStartsOnOwnLine"; - if($_>=1 and !${$self}{linebreaksAtEnd}{body}){ - # if the <body> statement doesn't finish with a line break, - # then we have different actions based upon the value of EndStartsOnOwnLine: - # EndStartsOnOwnLine == 1 just add a new line - # EndStartsOnOwnLine == 2 add a comment, and then new line - # EndStartsOnOwnLine == 3 add a blank line, and then new line - $logger->trace("Adding a linebreak at the end of body (see $EndStringLogFile)") if $is_t_switch_active; - - # by default, assume that no trailing character token is needed - my $trailingCharacterToken = q(); - if($_==2){ - $logger->trace("Adding a % immediately after body of ${$self}{name} ($EndStringLogFile==2)") if $is_t_switch_active; - $trailingCharacterToken = "%".$self->add_comment_symbol; + if ( defined ${$self}{EndStartsOnOwnLine} ) { + my $EndStringLogFile = ${$self}{aliases}{EndStartsOnOwnLine} || "EndStartsOnOwnLine"; + if ( $_ >= 1 and !${$self}{linebreaksAtEnd}{body} ) { + + # if the <body> statement doesn't finish with a line break, + # then we have different actions based upon the value of EndStartsOnOwnLine: + # EndStartsOnOwnLine == 1 just add a new line + # EndStartsOnOwnLine == 2 add a comment, and then new line + # EndStartsOnOwnLine == 3 add a blank line, and then new line + $logger->trace("Adding a linebreak at the end of body (see $EndStringLogFile)") if $is_t_switch_active; + + # by default, assume that no trailing character token is needed + my $trailingCharacterToken = q(); + if ( $_ == 2 ) { + $logger->trace("Adding a % immediately after body of ${$self}{name} ($EndStringLogFile==2)") + if $is_t_switch_active; + $trailingCharacterToken = "%" . $self->add_comment_symbol; ${$self}{body} =~ s/\h*$//s; - } elsif ($_==3) { - $logger->trace("Adding a blank line immediately after body of ${$self}{name} ($EndStringLogFile==3)") if $is_t_switch_active; - $trailingCharacterToken = "\n".(${$mainSettings{modifyLineBreaks}}{preserveBlankLines}?$tokens{blanklines}:q()); + } + elsif ( $_ == 3 ) { + $logger->trace( + "Adding a blank line immediately after body of ${$self}{name} ($EndStringLogFile==3)") + if $is_t_switch_active; + $trailingCharacterToken = "\n" + . ( ${ $mainSettings{modifyLineBreaks} }{preserveBlankLines} ? $tokens{blanklines} : q() ); ${$self}{body} =~ s/\h*$//s; - } - - # modified end statement - if(${$self}{body} =~ m/^\h*$/s and (defined ${$self}{BodyStartsOnOwnLine}) and ${$self}{BodyStartsOnOwnLine} >=1 ){ + } + + # modified end statement + if ( ${$self}{body} =~ m/^\h*$/s + and ( defined ${$self}{BodyStartsOnOwnLine} ) + and ${$self}{BodyStartsOnOwnLine} >= 1 ) + { ${$self}{linebreaksAtEnd}{body} = 0; - } else { + } + else { ${$self}{body} .= "$trailingCharacterToken\n"; ${$self}{linebreaksAtEnd}{body} = 1; - } - } elsif ($_==-1 and ${$self}{linebreaksAtEnd}{body}){ - # remove line break *after* body, if appropriate - - # check to see that body does *not* finish with blank-line-token, - # if so, then don't remove that final line break - if(${$self}{body} !~ m/$tokens{blanklines}$/s){ - $logger->trace("Removing linebreak at the end of body (see $EndStringLogFile)") if $is_t_switch_active; + } + } + elsif ( $_ == -1 and ${$self}{linebreaksAtEnd}{body} ) { + + # remove line break *after* body, if appropriate + + # check to see that body does *not* finish with blank-line-token, + # if so, then don't remove that final line break + if ( ${$self}{body} !~ m/$tokens{blanklines}$/s ) { + $logger->trace("Removing linebreak at the end of body (see $EndStringLogFile)") + if $is_t_switch_active; ${$self}{body} =~ s/\R*$//sx; ${$self}{linebreaksAtEnd}{body} = 0; - } else { - $logger->trace("Blank line token found at end of body (${$self}{name}), see preserveBlankLines, not removing line break before ${$self}{end}") if $is_t_switch_active; - } - } + } + else { + $logger->trace( + "Blank line token found at end of body (${$self}{name}), see preserveBlankLines, not removing line break before ${$self}{end}" + ) if $is_t_switch_active; + } + } } } - } +} -sub modify_line_breaks_end_after{ +sub modify_line_breaks_end_after { my $self = shift; - # + # # Blank line poly-switch notes (==4) # # when EndFinishesWithLineBreak=4 we adopt the following approach: @@ -165,139 +205,186 @@ sub modify_line_breaks_end_after{ # temporarily change EndFinishesWithLineBreak to 3, make adjustments # switch EndFinishesWithLineBreak back to 4 # - my @polySwitchValues =(${$self}{EndFinishesWithLineBreak}==4) ?(-1,3):(${$self}{EndFinishesWithLineBreak}); - foreach(@polySwitchValues){ - last if !(defined $_); - ${$self}{linebreaksAtEnd}{end} = 0 if($_==3 and (defined ${$self}{EndFinishesWithLineBreak} and ${$self}{EndFinishesWithLineBreak}==4)); + my @polySwitchValues + = ( ${$self}{EndFinishesWithLineBreak} == 4 ) ? ( -1, 3 ) : ( ${$self}{EndFinishesWithLineBreak} ); + foreach (@polySwitchValues) { + last if !( defined $_ ); + ${$self}{linebreaksAtEnd}{end} = 0 + if ( $_ == 3 + and ( defined ${$self}{EndFinishesWithLineBreak} and ${$self}{EndFinishesWithLineBreak} == 4 ) ); # possibly modify line break *after* \end{statement} - if(defined $_ and $_>=1 - and !${$self}{linebreaksAtEnd}{end} and ${$self}{end} ne ''){ - # if the <end> statement doesn't finish with a line break, - # then we have different actions based upon the value of EndFinishesWithLineBreak: - # EndFinishesWithLineBreak == 1 just add a new line - # EndFinishesWithLineBreak == 2 add a comment, and then new line - # EndFinishesWithLineBreak == 3 add a blank line, and then new line - my $EndStringLogFile = ${$self}{aliases}{EndFinishesWithLineBreak}||"EndFinishesWithLineBreak"; - if($_==1){ - $logger->trace("Adding a linebreak at the end of ${$self}{end} ($EndStringLogFile==1)") if $is_t_switch_active; - ${$self}{linebreaksAtEnd}{end} = 1; + if ( defined $_ + and $_ >= 1 + and !${$self}{linebreaksAtEnd}{end} + and ${$self}{end} ne '' ) + { + # if the <end> statement doesn't finish with a line break, + # then we have different actions based upon the value of EndFinishesWithLineBreak: + # EndFinishesWithLineBreak == 1 just add a new line + # EndFinishesWithLineBreak == 2 add a comment, and then new line + # EndFinishesWithLineBreak == 3 add a blank line, and then new line + my $EndStringLogFile = ${$self}{aliases}{EndFinishesWithLineBreak} || "EndFinishesWithLineBreak"; + if ( $_ == 1 ) { + $logger->trace("Adding a linebreak at the end of ${$self}{end} ($EndStringLogFile==1)") + if $is_t_switch_active; + ${$self}{linebreaksAtEnd}{end} = 1; - # modified end statement - ${$self}{replacementText} .= "\n"; - } elsif($_==2){ - if(${$self}{endImmediatelyFollowedByComment}){ - # no need to add a % if one already exists - $logger->trace("Even though $EndStringLogFile == 2, ${$self}{end} is immediately followed by a %, so not adding another; not adding line break.") if $is_t_switch_active; - } else { - # otherwise, create a trailing comment, and tack it on - $logger->trace("Adding a % immediately after ${$self}{end} ($EndStringLogFile==2)") if $is_t_switch_active; - my $trailingCommentToken = "%".$self->add_comment_symbol; - ${$self}{end} =~ s/\h*$//s; - ${$self}{replacementText} .= "$trailingCommentToken\n"; - ${$self}{linebreaksAtEnd}{end} = 1; - } - } elsif($_==3){ - $logger->trace("Adding a blank line at the end of ${$self}{end} ($EndStringLogFile==3)") if $is_t_switch_active; + # modified end statement + ${$self}{replacementText} .= "\n"; + } + elsif ( $_ == 2 ) { + if ( ${$self}{endImmediatelyFollowedByComment} ) { + + # no need to add a % if one already exists + $logger->trace( + "Even though $EndStringLogFile == 2, ${$self}{end} is immediately followed by a %, so not adding another; not adding line break." + ) if $is_t_switch_active; + } + else { + # otherwise, create a trailing comment, and tack it on + $logger->trace("Adding a % immediately after ${$self}{end} ($EndStringLogFile==2)") + if $is_t_switch_active; + my $trailingCommentToken = "%" . $self->add_comment_symbol; + ${$self}{end} =~ s/\h*$//s; + ${$self}{replacementText} .= "$trailingCommentToken\n"; ${$self}{linebreaksAtEnd}{end} = 1; + } + } + elsif ( $_ == 3 ) { + $logger->trace("Adding a blank line at the end of ${$self}{end} ($EndStringLogFile==3)") + if $is_t_switch_active; + ${$self}{linebreaksAtEnd}{end} = 1; - # modified end statement - ${$self}{replacementText} .= (${$mainSettings{modifyLineBreaks}}{preserveBlankLines}?$tokens{blanklines}:"\n")."\n"; - } + # modified end statement + ${$self}{replacementText} + .= ( ${ $mainSettings{modifyLineBreaks} }{preserveBlankLines} ? $tokens{blanklines} : "\n" ) . "\n"; + } } } } -sub adjust_line_breaks_end_parent{ +sub adjust_line_breaks_end_parent { + # when a parent object contains a child object, the line break # at the end of the parent object can become messy my $self = shift; # most recent child object - my $child = @{${$self}{children}}[-1]; + my $child = @{ ${$self}{children} }[-1]; # adjust parent linebreaks information - if(${$child}{linebreaksAtEnd}{end} and ${$self}{body} =~ m/${$child}{replacementText}\h*\R*$/s and !${$self}{linebreaksAtEnd}{body}){ - $logger->trace("ID: ${$child}{id}") if($is_t_switch_active); - $logger->trace("${$child}{begin}...${$child}{end} is found at the END of body of parent, ${$self}{name}, avoiding a double line break:") if($is_t_switch_active); - $logger->trace("adjusting ${$self}{name} linebreaksAtEnd{body} to be 1") if($is_t_switch_active); - ${$self}{linebreaksAtEnd}{body}=1; - } - - # the modify line switch can adjust line breaks, so we need another check, + if ( ${$child}{linebreaksAtEnd}{end} + and ${$self}{body} =~ m/${$child}{replacementText}\h*\R*$/s + and !${$self}{linebreaksAtEnd}{body} ) + { + $logger->trace("ID: ${$child}{id}") if ($is_t_switch_active); + $logger->trace( + "${$child}{begin}...${$child}{end} is found at the END of body of parent, ${$self}{name}, avoiding a double line break:" + ) if ($is_t_switch_active); + $logger->trace("adjusting ${$self}{name} linebreaksAtEnd{body} to be 1") if ($is_t_switch_active); + ${$self}{linebreaksAtEnd}{body} = 1; + } + + # the modify line switch can adjust line breaks, so we need another check, # see for example, test-cases/environments/environments-remove-line-breaks-trailing-comments.tex - if(defined ${$child}{linebreaksAtEnd}{body} - and !${$child}{linebreaksAtEnd}{body} - and ${$child}{body} =~ m/\R(?:$trailingCommentRegExp\h*)?$/s ){ + if ( defined ${$child}{linebreaksAtEnd}{body} + and !${$child}{linebreaksAtEnd}{body} + and ${$child}{body} =~ m/\R(?:$trailingCommentRegExp\h*)?$/s ) + { # log file information - $logger->trace("Undisclosed line break at the end of body of ${$child}{name}: '${$child}{end}'") if($is_t_switch_active); - $logger->trace("Adding a linebreak at the end of body for ${$child}{id}") if($is_t_switch_active); - + $logger->trace("Undisclosed line break at the end of body of ${$child}{name}: '${$child}{end}'") + if ($is_t_switch_active); + $logger->trace("Adding a linebreak at the end of body for ${$child}{id}") if ($is_t_switch_active); + # make the adjustments ${$child}{body} .= "\n"; - ${$child}{linebreaksAtEnd}{body}=1; + ${$child}{linebreaksAtEnd}{body} = 1; } } -sub verbatim_modify_line_breaks{ - # verbatim modify line breaks are a bit special, as they happen before +sub verbatim_modify_line_breaks { + + # verbatim modify line breaks are a bit special, as they happen before # any of the main processes have been done - my $self = shift; + my $self = shift; my %input = @_; - while ( my ($key,$child)= each %verbatimStorage){ - if(defined ${$child}{BeginStartsOnOwnLine}){ - my $BeginStringLogFile = ${$child}{aliases}{BeginStartsOnOwnLine}; - $logger->trace("*$BeginStringLogFile is ${$child}{BeginStartsOnOwnLine} for ${$child}{name}") if $is_t_switch_active ; - if (${$child}{BeginStartsOnOwnLine}==-1){ - # VerbatimStartsOnOwnLine = -1 - if(${$self}{body}=~m/^\h*${$child}{id}/m){ - $logger->trace("${$child}{name} begins on its own line, removing leading line break") if $is_t_switch_active ; - ${$self}{body} =~ s/(\R|\h)*${$child}{id}/${$child}{id}/s; + while ( my ( $key, $child ) = each %verbatimStorage ) { + if ( defined ${$child}{BeginStartsOnOwnLine} ) { + my $BeginStringLogFile = ${$child}{aliases}{BeginStartsOnOwnLine}; + $logger->trace("*$BeginStringLogFile is ${$child}{BeginStartsOnOwnLine} for ${$child}{name}") + if $is_t_switch_active; + if ( ${$child}{BeginStartsOnOwnLine} == -1 ) { + + # VerbatimStartsOnOwnLine = -1 + if ( ${$self}{body} =~ m/^\h*${$child}{id}/m ) { + $logger->trace("${$child}{name} begins on its own line, removing leading line break") + if $is_t_switch_active; + ${$self}{body} =~ s/(\R|\h)*${$child}{id}/${$child}{id}/s; + } } - } elsif (${$child}{BeginStartsOnOwnLine}>=1 and ${$self}{body}!~m/^\h*${$child}{id}/m){ - # VerbatimStartsOnOwnLine = 1, 2 or 3 - my $trailingCharacterToken = q(); - if(${$child}{BeginStartsOnOwnLine}==1){ - $logger->trace("Adding a linebreak at the beginning of ${$child}{begin} (see $BeginStringLogFile)") if $is_t_switch_active; - } elsif (${$child}{BeginStartsOnOwnLine}==2){ - $logger->trace("Adding a % at the end of the line that ${$child}{begin} is on, then a linebreak ($BeginStringLogFile == 2)") if $is_t_switch_active; - $trailingCharacterToken = "%".$self->add_comment_symbol; - } elsif (${$child}{BeginStartsOnOwnLine}==3){ - $logger->trace("Adding a blank line at the end of the line that ${$child}{begin} is on, then a linebreak ($BeginStringLogFile == 3)") if $is_t_switch_active; - $trailingCharacterToken = "\n"; + elsif ( ${$child}{BeginStartsOnOwnLine} >= 1 and ${$self}{body} !~ m/^\h*${$child}{id}/m ) { + + # VerbatimStartsOnOwnLine = 1, 2 or 3 + my $trailingCharacterToken = q(); + if ( ${$child}{BeginStartsOnOwnLine} == 1 ) { + $logger->trace("Adding a linebreak at the beginning of ${$child}{begin} (see $BeginStringLogFile)") + if $is_t_switch_active; + } + elsif ( ${$child}{BeginStartsOnOwnLine} == 2 ) { + $logger->trace( + "Adding a % at the end of the line that ${$child}{begin} is on, then a linebreak ($BeginStringLogFile == 2)" + ) if $is_t_switch_active; + $trailingCharacterToken = "%" . $self->add_comment_symbol; + } + elsif ( ${$child}{BeginStartsOnOwnLine} == 3 ) { + $logger->trace( + "Adding a blank line at the end of the line that ${$child}{begin} is on, then a linebreak ($BeginStringLogFile == 3)" + ) if $is_t_switch_active; + $trailingCharacterToken = "\n"; + } + ${$self}{body} =~ s/\h*${$child}{id}/$trailingCharacterToken\n${$child}{id}/s; } - ${$self}{body} =~ s/\h*${$child}{id}/$trailingCharacterToken\n${$child}{id}/s; } - } - - # after text wrap poly-switch check - if ($input{when} eq "afterTextWrap"){ - $logger->trace("*post text wrap poly-switch check for EndFinishesWithLineBreak") if $is_t_switch_active ; - if (defined ${$child}{EndFinishesWithLineBreak} - and ${$child}{EndFinishesWithLineBreak}>=1 - and ${$self}{body} =~m/${$child}{id}\h*\S+/m){ - ${$child}{linebreaksAtEnd}{end} = 1; - - # by default, assume that no trailing comment token is needed - my $trailingCommentToken = q(); - my $lineBreakCharacter = q(); - my $EndStringLogFile = ${$self}{aliases}{EndStartsOnOwnLine}||"EndStartsOnOwnLine"; - - if(${$child}{EndFinishesWithLineBreak}==1){ - $logger->trace("Adding a linebreak at the end of ${$child}{end} (post text wrap $EndStringLogFile==1)") if $is_t_switch_active; - $lineBreakCharacter = "\n"; - } elsif(${$child}{EndFinishesWithLineBreak}==2 and ${$self}{body} !~ m/${$child}{id}\h*$trailingCommentRegExp/s){ - $logger->trace("Adding a % immediately after ${$child}{end} (post text wrap $EndStringLogFile==2)") if $is_t_switch_active; - $trailingCommentToken = "%".$self->add_comment_symbol."\n"; - } elsif(${$child}{EndFinishesWithLineBreak}==3){ - $lineBreakCharacter .= (${$mainSettings{modifyLineBreaks}}{preserveBlankLines}?$tokens{blanklines}:"\n")."\n"; - } - ${$self}{body} =~s/${$child}{id}(\h*)/${$child}{id}$1$trailingCommentToken$lineBreakCharacter/s; + + # after text wrap poly-switch check + if ( $input{when} eq "afterTextWrap" ) { + $logger->trace("*post text wrap poly-switch check for EndFinishesWithLineBreak") if $is_t_switch_active; + if ( defined ${$child}{EndFinishesWithLineBreak} + and ${$child}{EndFinishesWithLineBreak} >= 1 + and ${$self}{body} =~ m/${$child}{id}\h*\S+/m ) + { + ${$child}{linebreaksAtEnd}{end} = 1; + + # by default, assume that no trailing comment token is needed + my $trailingCommentToken = q(); + my $lineBreakCharacter = q(); + my $EndStringLogFile = ${$self}{aliases}{EndStartsOnOwnLine} || "EndStartsOnOwnLine"; + + if ( ${$child}{EndFinishesWithLineBreak} == 1 ) { + $logger->trace( + "Adding a linebreak at the end of ${$child}{end} (post text wrap $EndStringLogFile==1)") + if $is_t_switch_active; + $lineBreakCharacter = "\n"; + } + elsif ( ${$child}{EndFinishesWithLineBreak} == 2 + and ${$self}{body} !~ m/${$child}{id}\h*$trailingCommentRegExp/s ) + { + $logger->trace("Adding a % immediately after ${$child}{end} (post text wrap $EndStringLogFile==2)") + if $is_t_switch_active; + $trailingCommentToken = "%" . $self->add_comment_symbol . "\n"; + } + elsif ( ${$child}{EndFinishesWithLineBreak} == 3 ) { + $lineBreakCharacter + .= ( ${ $mainSettings{modifyLineBreaks} }{preserveBlankLines} ? $tokens{blanklines} : "\n" ) + . "\n"; + } + ${$self}{body} =~ s/${$child}{id}(\h*)/${$child}{id}$1$trailingCommentToken$lineBreakCharacter/s; + } } - } } } diff --git a/Master/texmf-dist/scripts/latexindent/LatexIndent/NamedGroupingBracesBrackets.pm b/Master/texmf-dist/scripts/latexindent/LatexIndent/NamedGroupingBracesBrackets.pm index 23634075927..f9839e09aaf 100755 --- a/Master/texmf-dist/scripts/latexindent/LatexIndent/NamedGroupingBracesBrackets.pm +++ b/Master/texmf-dist/scripts/latexindent/LatexIndent/NamedGroupingBracesBrackets.pm @@ -1,4 +1,5 @@ package LatexIndent::NamedGroupingBracesBrackets; + # 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 @@ -22,13 +23,14 @@ use LatexIndent::TrailingComments qw/$trailingCommentRegExp/; use LatexIndent::Switches qw/$is_t_switch_active $is_tt_switch_active/; use LatexIndent::LogFile qw/$logger/; use Exporter qw/import/; -our @ISA = "LatexIndent::Command"; # class inheritance, Programming Perl, pg 321 -our @EXPORT_OK = qw/construct_grouping_braces_brackets_regexp $grouping_braces_regexp $grouping_braces_regexpTrailingComment/; +our @ISA = "LatexIndent::Command"; # class inheritance, Programming Perl, pg 321 +our @EXPORT_OK + = qw/construct_grouping_braces_brackets_regexp $grouping_braces_regexp $grouping_braces_regexpTrailingComment/; our $groupingBracesCounter; -our $grouping_braces_regexp; -our $grouping_braces_regexpTrailingComment; +our $grouping_braces_regexp; +our $grouping_braces_regexpTrailingComment; -sub construct_grouping_braces_brackets_regexp{ +sub construct_grouping_braces_brackets_regexp { my $self = shift; # grab the arguments regexp @@ -36,30 +38,34 @@ sub construct_grouping_braces_brackets_regexp{ # read from fine tuning my $NamedGroupingBracesBracketsRegExp = qr/${${$mainSettings{fineTuning}}{namedGroupingBracesBrackets}}{name}/; - my $NamedGroupingFollowRegExp = qr/${${$mainSettings{fineTuning}}{namedGroupingBracesBrackets}}{follow}/; + my $NamedGroupingFollowRegExp = qr/${${$mainSettings{fineTuning}}{namedGroupingBracesBrackets}}{follow}/; - # defaultSettings.yaml mistakenly had + # defaultSettings.yaml mistakenly had # # fineTuning: # NamedGroupingBracesBrackets: - # - # when it should have been + # + # when it should have been # # fineTuning: # namedGroupingBracesBrackets: # - # the mistake was mine, so I feel that the following is necessary; if we + # the mistake was mine, so I feel that the following is necessary; if we # get to V4, then this will be removed and only namedGroupingBracesBrackets will be supported - if(${${$mainSettings{fineTuning}}{NamedGroupingBracesBrackets}}{name}){ - $logger->warn("*fineTuning:NamedGroupingBracesBrackets is ok for now, but in future versions, fineTuning:namedGroupingBracesBrackets will be used"); + if ( ${ ${ $mainSettings{fineTuning} }{NamedGroupingBracesBrackets} }{name} ) { + $logger->warn( + "*fineTuning:NamedGroupingBracesBrackets is ok for now, but in future versions, fineTuning:namedGroupingBracesBrackets will be used" + ); $NamedGroupingBracesBracketsRegExp = qr/${${$mainSettings{fineTuning}}{NamedGroupingBracesBrackets}}{name}/; - } - if(${${$mainSettings{fineTuning}}{NamedGroupingBracesBrackets}}{follow}){ - $logger->warn("*fineTuning:NamedGroupingBracesBrackets is ok for now, but in future versions, fineTuning:namedGroupingBracesBrackets will be used"); + } + if ( ${ ${ $mainSettings{fineTuning} }{NamedGroupingBracesBrackets} }{follow} ) { + $logger->warn( + "*fineTuning:NamedGroupingBracesBrackets is ok for now, but in future versions, fineTuning:namedGroupingBracesBrackets will be used" + ); $NamedGroupingFollowRegExp = qr/${${$mainSettings{fineTuning}}{NamedGroupingBracesBrackets}}{follow}/; } - # store the regular expresssion for matching and replacing + # store the regular expresssion for matching and replacing $grouping_braces_regexp = qr/ ( $NamedGroupingFollowRegExp @@ -78,7 +84,7 @@ sub construct_grouping_braces_brackets_regexp{ } -sub create_unique_id{ +sub create_unique_id { my $self = shift; $groupingBracesCounter++; @@ -86,12 +92,12 @@ sub create_unique_id{ return; } -sub get_replacement_text{ +sub get_replacement_text { my $self = shift; - # the replacement text for a key = {value} needes to accomodate the leading [ OR { OR % OR , OR any combination thereof + # the replacement text for a key = {value} needes to accomodate the leading [ OR { OR % OR , OR any combination thereof $logger->trace("Custom replacement text routine for ${$self}{name}") if $is_t_switch_active; - ${$self}{replacementText} = ${$self}{beginningbit}.${$self}{id}; + ${$self}{replacementText} = ${$self}{beginningbit} . ${$self}{id}; delete ${$self}{beginningbit}; } diff --git a/Master/texmf-dist/scripts/latexindent/LatexIndent/OptionalArgument.pm b/Master/texmf-dist/scripts/latexindent/LatexIndent/OptionalArgument.pm index 31e7b8f51e1..90dba063b95 100644 --- a/Master/texmf-dist/scripts/latexindent/LatexIndent/OptionalArgument.pm +++ b/Master/texmf-dist/scripts/latexindent/LatexIndent/OptionalArgument.pm @@ -1,4 +1,5 @@ package LatexIndent::OptionalArgument; + # 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 @@ -23,7 +24,7 @@ use LatexIndent::LogFile qw/$logger/; use LatexIndent::IfElseFi qw/$ifElseFiBasicRegExp/; use LatexIndent::Special qw/$specialBeginBasicRegExp/; use Exporter qw/import/; -our @ISA = "LatexIndent::Document"; # class inheritance, Programming Perl, pg 321 +our @ISA = "LatexIndent::Document"; # class inheritance, Programming Perl, pg 321 our @EXPORT_OK = qw/find_optional_arguments/; our $optionalArgumentCounter; our $optArgRegExp = qr/ @@ -43,14 +44,15 @@ our $optArgRegExp = qr/ (\R)? /sx; -sub find_optional_arguments{ +sub find_optional_arguments { my $self = shift; # pick out the optional arguments - while(${$self}{body} =~ m/$optArgRegExp\h*($trailingCommentRegExp)*(.*)/s){ + while ( ${$self}{body} =~ m/$optArgRegExp\h*($trailingCommentRegExp)*(.*)/s ) { + # log file output $logger->trace("*Optional argument found, body in ${$self}{name}") if $is_t_switch_active; - $logger->trace("(last argument)") if($9 eq '' and $is_t_switch_active); + $logger->trace("(last argument)") if ( $9 eq '' and $is_t_switch_active ); ${$self}{body} =~ s/ $optArgRegExp(\h*)($trailingCommentRegExp)*(.*) @@ -87,16 +89,16 @@ sub find_optional_arguments{ $self->get_settings_and_store_new_object($optionalArg); ${@{${$self}{children}}[-1]}{replacementText}.($8?$8:q()).($9?$9:q()).($10?$10:q()); /xseg; - } - } + } +} -sub yaml_get_object_attribute_for_indentation_settings{ +sub yaml_get_object_attribute_for_indentation_settings { my $self = shift; - + return ${$self}{modifyLineBreaksYamlName}; } -sub create_unique_id{ +sub create_unique_id { my $self = shift; $optionalArgumentCounter++; @@ -104,15 +106,17 @@ sub create_unique_id{ return; } -sub tasks_particular_to_each_object{ +sub tasks_particular_to_each_object { my $self = shift; # lookForAlignDelims: lookForChildCodeBlocks set to 0 means no child objects searched for # see: test-cases/alignment/issue-308-command.tex # - if( defined ${$self}{lookForChildCodeBlocks} and !${$self}{lookForChildCodeBlocks} ){ - $logger->trace("lookForAlignDelims: lookForChildCodeBlocks set to 0, so child objects will *NOT* be searched for") if($is_t_switch_active); - return; + if ( defined ${$self}{lookForChildCodeBlocks} and !${$self}{lookForChildCodeBlocks} ) { + $logger->trace( + "lookForAlignDelims: lookForChildCodeBlocks set to 0, so child objects will *NOT* be searched for") + if ($is_t_switch_active); + return; } # search for ifElseFi blocks diff --git a/Master/texmf-dist/scripts/latexindent/LatexIndent/Preamble.pm b/Master/texmf-dist/scripts/latexindent/LatexIndent/Preamble.pm index bade8d42d11..7f835e6d0d5 100644 --- a/Master/texmf-dist/scripts/latexindent/LatexIndent/Preamble.pm +++ b/Master/texmf-dist/scripts/latexindent/LatexIndent/Preamble.pm @@ -1,4 +1,5 @@ package LatexIndent::Preamble; + # 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 @@ -23,10 +24,10 @@ use LatexIndent::LogFile qw/$logger/; use LatexIndent::Environment qw/$environmentBasicRegExp/; use LatexIndent::IfElseFi qw/$ifElseFiBasicRegExp/; use LatexIndent::Special qw/$specialBeginBasicRegExp/; -our @ISA = "LatexIndent::Document"; # class inheritance, Programming Perl, pg 321 +our @ISA = "LatexIndent::Document"; # class inheritance, Programming Perl, pg 321 our $preambleCounter; -sub create_unique_id{ +sub create_unique_id { my $self = shift; $preambleCounter++; @@ -34,21 +35,22 @@ sub create_unique_id{ return; } -sub get_replacement_text{ +sub get_replacement_text { my $self = shift; # the replacement text for preamble needs to put the \\begin{document} back in $logger->trace("Custom replacement text routine for preamble ${$self}{name}") if $is_t_switch_active; - ${$self}{replacementText} = ${$self}{id}.${$self}{afterbit}; + ${$self}{replacementText} = ${$self}{id} . ${$self}{afterbit}; delete ${$self}{afterbit}; } -sub indent{ +sub indent { + # preamble doesn't receive any additional indentation return; } -sub tasks_particular_to_each_object{ +sub tasks_particular_to_each_object { my $self = shift; # search for environments @@ -57,15 +59,17 @@ sub tasks_particular_to_each_object{ # search for ifElseFi blocks $self->find_ifelsefi if ${$self}{body} =~ m/$ifElseFiBasicRegExp/s; - if(${$mainSettings{specialBeginEnd}}{specialBeforeCommand}){ + if ( ${ $mainSettings{specialBeginEnd} }{specialBeforeCommand} ) { + # search for special begin/end $self->find_special if ${$self}{body} =~ m/$specialBeginBasicRegExp/s; # search for commands with arguments - $self->find_commands_or_key_equals_values_braces if(!$mainSettings{preambleCommandsBeforeEnvironments}); - } else { + $self->find_commands_or_key_equals_values_braces if ( !$mainSettings{preambleCommandsBeforeEnvironments} ); + } + else { # search for commands with arguments - $self->find_commands_or_key_equals_values_braces if(!$mainSettings{preambleCommandsBeforeEnvironments}); + $self->find_commands_or_key_equals_values_braces if ( !$mainSettings{preambleCommandsBeforeEnvironments} ); # search for special begin/end $self->find_special if ${$self}{body} =~ m/$specialBeginBasicRegExp/s; diff --git a/Master/texmf-dist/scripts/latexindent/LatexIndent/Replacement.pm b/Master/texmf-dist/scripts/latexindent/LatexIndent/Replacement.pm index e387d11b4c7..707010e9661 100644 --- a/Master/texmf-dist/scripts/latexindent/LatexIndent/Replacement.pm +++ b/Master/texmf-dist/scripts/latexindent/LatexIndent/Replacement.pm @@ -1,4 +1,5 @@ package LatexIndent::Replacement; + # 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 @@ -22,65 +23,70 @@ use LatexIndent::GetYamlSettings qw/%mainSettings/; use LatexIndent::Switches qw/$is_t_switch_active $is_tt_switch_active $is_rr_switch_active/; use LatexIndent::LogFile qw/$logger/; use Exporter qw/import/; -our @ISA = "LatexIndent::Document"; # class inheritance, Programming Perl, pg 321 +our @ISA = "LatexIndent::Document"; # class inheritance, Programming Perl, pg 321 our @EXPORT_OK = qw/make_replacements/; -sub make_replacements{ - my $self = shift; +sub make_replacements { + my $self = shift; my %input = @_; - if ($is_t_switch_active and !$is_rr_switch_active){ - $logger->trace("*Replacement mode *$input{when}* indentation: -r") ; - } elsif ($is_t_switch_active and $is_rr_switch_active) { - $logger->trace("*Replacement mode, -rr switch is active") if $is_t_switch_active ; + if ( $is_t_switch_active and !$is_rr_switch_active ) { + $logger->trace("*Replacement mode *$input{when}* indentation: -r"); + } + elsif ( $is_t_switch_active and $is_rr_switch_active ) { + $logger->trace("*Replacement mode, -rr switch is active") if $is_t_switch_active; } - my @replacements = @{$mainSettings{replacements}}; + my @replacements = @{ $mainSettings{replacements} }; + + foreach (@replacements) { + next if !( ${$_}{this} or ${$_}{substitution} ); - foreach ( @replacements ){ - next if !(${$_}{this} or ${$_}{substitution}); - # default value of "lookForThis" is 1 - ${$_}{lookForThis} = 1 if( !(defined ${$_}{lookForThis})); + ${$_}{lookForThis} = 1 if ( !( defined ${$_}{lookForThis} ) ); # move on if this one shouldn't be looked for - next if(!${$_}{lookForThis}); + next if ( !${$_}{lookForThis} ); # default value of "when" is before - ${$_}{when} = "before" if( !(defined ${$_}{when}) or $is_rr_switch_active); - + ${$_}{when} = "before" if ( !( defined ${$_}{when} ) or $is_rr_switch_active ); + # update to the logging file - if($is_t_switch_active and (${$_}{when} eq $input{when})){ + if ( $is_t_switch_active and ( ${$_}{when} eq $input{when} ) ) { $logger->trace("-"); - $logger->trace("this: ${$_}{this}") if(${$_}{this}); - $logger->trace("that: ${$_}{that}") if(${$_}{that}); - $logger->trace("substitution: ${$_}{substitution}") if(${$_}{substitution}); + $logger->trace("this: ${$_}{this}") if ( ${$_}{this} ); + $logger->trace("that: ${$_}{that}") if ( ${$_}{that} ); + $logger->trace("substitution: ${$_}{substitution}") if ( ${$_}{substitution} ); $logger->trace("when: ${$_}{when}"); } # perform the substitutions - if(${$_}{when} eq $input{when}){ - $logger->warn("*You have specified both 'this' and 'substitution'; the 'substitution' field will be ignored") if(${$_}{this} and ${$_}{substitution}); - if(${$_}{this}){ + if ( ${$_}{when} eq $input{when} ) { + $logger->warn( + "*You have specified both 'this' and 'substitution'; the 'substitution' field will be ignored") + if ( ${$_}{this} and ${$_}{substitution} ); + if ( ${$_}{this} ) { + # *string* replacement # *string* replacement # *string* replacement - my $this = qq{${$_}{this}}; - my $that = (defined ${$_}{that}) ? qq{${$_}{that}} : q(); - my $index_match = index(${$self}{body}, $this); - while ( $index_match != -1 ) { - substr (${$self}{body}, $index_match, length($this), $that ); - $index_match = index(${$self}{body}, $this); - } - } else { + my $this = qq{${$_}{this}}; + my $that = ( defined ${$_}{that} ) ? qq{${$_}{that}} : q(); + my $index_match = index( ${$self}{body}, $this ); + while ( $index_match != -1 ) { + substr( ${$self}{body}, $index_match, length($this), $that ); + $index_match = index( ${$self}{body}, $this ); + } + } + else { # *regex* replacement # *regex* replacement # *regex* replacement - - # https://stackoverflow.com/questions/12423337/how-to-pass-a-replacing-regex-as-a-command-line-argument-to-a-perl-script - my $body = ${$self}{body}; + +# https://stackoverflow.com/questions/12423337/how-to-pass-a-replacing-regex-as-a-command-line-argument-to-a-perl-script + my $body = ${$self}{body}; eval("\$body =~ ${$_}{substitution}"); - ${$self}{body} = $body ; - } + ${$self}{body} = $body; + } } } } diff --git a/Master/texmf-dist/scripts/latexindent/LatexIndent/RoundBrackets.pm b/Master/texmf-dist/scripts/latexindent/LatexIndent/RoundBrackets.pm index fff5efedd00..9b6f4aa8dd8 100644 --- a/Master/texmf-dist/scripts/latexindent/LatexIndent/RoundBrackets.pm +++ b/Master/texmf-dist/scripts/latexindent/LatexIndent/RoundBrackets.pm @@ -1,4 +1,5 @@ package LatexIndent::RoundBrackets; + # 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 @@ -20,7 +21,7 @@ use LatexIndent::Tokens qw/%tokens/; use LatexIndent::TrailingComments qw/$trailingCommentRegExp/; use LatexIndent::Switches qw/$is_t_switch_active $is_tt_switch_active/; use Exporter qw/import/; -our @ISA = "LatexIndent::Document"; # class inheritance, Programming Perl, pg 321 +our @ISA = "LatexIndent::Document"; # class inheritance, Programming Perl, pg 321 our @EXPORT_OK = qw/find_round_brackets/; our $roundBracketCounter; our $roundBracketRegExp = qr/ @@ -40,15 +41,16 @@ our $roundBracketRegExp = qr/ (\R)? /sx; -sub indent{ +sub indent { return; } -sub find_round_brackets{ +sub find_round_brackets { my $self = shift; # pick out the optional arguments - while(${$self}{body} =~ m/$roundBracketRegExp\h*($trailingCommentRegExp)*(.*)/s){ + while ( ${$self}{body} =~ m/$roundBracketRegExp\h*($trailingCommentRegExp)*(.*)/s ) { + # log file output ${$self}{body} =~ s/ @@ -76,16 +78,16 @@ sub find_round_brackets{ $self->get_settings_and_store_new_object($roundBracket); ${@{${$self}{children}}[-1]}{replacementText}.($8?$8:q()).($9?$9:q()).($10?$10:q()); /xseg; - } - } + } +} -sub yaml_get_object_attribute_for_indentation_settings{ +sub yaml_get_object_attribute_for_indentation_settings { my $self = shift; - + return ${$self}{modifyLineBreaksYamlName}; } -sub create_unique_id{ +sub create_unique_id { my $self = shift; $roundBracketCounter++; @@ -93,7 +95,7 @@ sub create_unique_id{ return; } -sub tasks_particular_to_each_object{ +sub tasks_particular_to_each_object { return; } diff --git a/Master/texmf-dist/scripts/latexindent/LatexIndent/Sentence.pm b/Master/texmf-dist/scripts/latexindent/LatexIndent/Sentence.pm index f2120ee7f87..cee8b559ab5 100644 --- a/Master/texmf-dist/scripts/latexindent/LatexIndent/Sentence.pm +++ b/Master/texmf-dist/scripts/latexindent/LatexIndent/Sentence.pm @@ -1,4 +1,5 @@ package LatexIndent::Sentence; + # 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 @@ -26,25 +27,30 @@ use LatexIndent::IfElseFi qw/$ifElseFiBasicRegExp/; use LatexIndent::Heading qw/$allHeadingsRegexp/; use LatexIndent::Special qw/$specialBeginAndBracesBracketsBasicRegExp/; use Exporter qw/import/; -our @ISA = "LatexIndent::Document"; # class inheritance, Programming Perl, pg 321 +our @ISA = "LatexIndent::Document"; # class inheritance, Programming Perl, pg 321 our @EXPORT_OK = qw/one_sentence_per_line/; our $sentenceCounter; -sub one_sentence_per_line{ +sub one_sentence_per_line { my $self = shift; - $logger->trace("*One sentence per line regular expression construction: (see oneSentencePerLine: manipulateSentences)") if $is_t_switch_active; + $logger->trace( + "*One sentence per line regular expression construction: (see oneSentencePerLine: manipulateSentences)") + if $is_t_switch_active; # sentences FOLLOW # sentences FOLLOW # sentences FOLLOW my $sentencesFollow = q(); - while( my ($sentencesFollowEachPart,$yesNo)= each %{${$mainSettings{modifyLineBreaks}{oneSentencePerLine}}{sentencesFollow}}){ - if($yesNo){ - if($sentencesFollowEachPart eq "par"){ + while ( my ( $sentencesFollowEachPart, $yesNo ) + = each %{ ${ $mainSettings{modifyLineBreaks}{oneSentencePerLine} }{sentencesFollow} } ) + { + if ($yesNo) { + if ( $sentencesFollowEachPart eq "par" ) { $sentencesFollowEachPart = qr/\R?\\par/s; - } elsif ($sentencesFollowEachPart eq "blankLine"){ + } + elsif ( $sentencesFollowEachPart eq "blankLine" ) { $sentencesFollowEachPart = qr/ (?:\A(?:$tokens{blanklines}\R)+) # the order of each of these | # is important, as (like always) the first @@ -56,61 +62,76 @@ sub one_sentence_per_line{ | \G /sx; - } elsif ($sentencesFollowEachPart eq "fullStop"){ + } + elsif ( $sentencesFollowEachPart eq "fullStop" ) { $sentencesFollowEachPart = qr/\./s; - } elsif ($sentencesFollowEachPart eq "exclamationMark"){ + } + elsif ( $sentencesFollowEachPart eq "exclamationMark" ) { $sentencesFollowEachPart = qr/\!/s; - } elsif ($sentencesFollowEachPart eq "questionMark"){ + } + elsif ( $sentencesFollowEachPart eq "questionMark" ) { $sentencesFollowEachPart = qr/\?/s; - } elsif ($sentencesFollowEachPart eq "rightBrace"){ + } + elsif ( $sentencesFollowEachPart eq "rightBrace" ) { $sentencesFollowEachPart = qr/\}/s; - } elsif ($sentencesFollowEachPart eq "commentOnPreviousLine"){ + } + elsif ( $sentencesFollowEachPart eq "commentOnPreviousLine" ) { $sentencesFollowEachPart = qr/$trailingCommentRegExp\h*\R/s; - } elsif ($sentencesFollowEachPart eq "other"){ + } + elsif ( $sentencesFollowEachPart eq "other" ) { $sentencesFollowEachPart = qr/$yesNo/; } - $sentencesFollow .= ($sentencesFollow eq '' ? q() : "|").qr/$sentencesFollowEachPart/sx; + $sentencesFollow .= ( $sentencesFollow eq '' ? q() : "|" ) . qr/$sentencesFollowEachPart/sx; } } - # if blankLine is not active from sentencesFollow then we need to set up the - # beginning of the string, but make sure that it is *not* followed by a + + # if blankLine is not active from sentencesFollow then we need to set up the + # beginning of the string, but make sure that it is *not* followed by a # blank line token, or a blank line - if(!${${$mainSettings{modifyLineBreaks}{oneSentencePerLine}}{sentencesFollow}}{blankLine}){ - $sentencesFollow .= ($sentencesFollow eq '' ? q() : "|"). - qr/ + if ( !${ ${ $mainSettings{modifyLineBreaks}{oneSentencePerLine} }{sentencesFollow} }{blankLine} ) { + $sentencesFollow .= ( $sentencesFollow eq '' ? q() : "|" ) . qr/ \G (?!$tokens{blanklines}) /sx; } - if(${${$mainSettings{modifyLineBreaks}{oneSentencePerLine}}{sentencesFollow}}{blankLine}){ - $sentencesFollow = ($sentencesFollow eq '' ? q() : qr/(?:$sentencesFollow)(?:\h|\R)*/sx ); - } else { - $sentencesFollow = ($sentencesFollow eq '' ? q() : qr/(?:$sentencesFollow)(?:\h*\R?)/sx ); + if ( ${ ${ $mainSettings{modifyLineBreaks}{oneSentencePerLine} }{sentencesFollow} }{blankLine} ) { + $sentencesFollow = ( $sentencesFollow eq '' ? q() : qr/(?:$sentencesFollow)(?:\h|\R)*/sx ); + } + else { + $sentencesFollow = ( $sentencesFollow eq '' ? q() : qr/(?:$sentencesFollow)(?:\h*\R?)/sx ); } - $logger->trace("Sentences follow regexp:") if $is_tt_switch_active; $logger->trace($sentencesFollow) if $is_tt_switch_active; - + # sentences BEGIN with # sentences BEGIN with # sentences BEGIN with my $sentencesBeginWith = q(); - while( my ($sentencesBeginWithEachPart,$yesNo)= each %{${$mainSettings{modifyLineBreaks}{oneSentencePerLine}}{sentencesBeginWith}}){ - if($yesNo){ - if($sentencesBeginWithEachPart eq "A-Z"){ - $logger->trace("sentence BEGINS with capital letters (see oneSentencePerLine:sentencesBeginWith:A-Z)") if $is_t_switch_active; + while ( my ( $sentencesBeginWithEachPart, $yesNo ) + = each %{ ${ $mainSettings{modifyLineBreaks}{oneSentencePerLine} }{sentencesBeginWith} } ) + { + if ($yesNo) { + if ( $sentencesBeginWithEachPart eq "A-Z" ) { + $logger->trace("sentence BEGINS with capital letters (see oneSentencePerLine:sentencesBeginWith:A-Z)") + if $is_t_switch_active; $sentencesBeginWithEachPart = qr/(?!(?:$tokens{blanklines}|$tokens{verbatim}|$tokens{preamble}))[A-Z]/; - } elsif ($sentencesBeginWithEachPart eq "a-z"){ - $logger->trace("sentence BEGINS with lower-case letters (see oneSentencePerLine:sentencesBeginWith:a-z)") if $is_t_switch_active; + } + elsif ( $sentencesBeginWithEachPart eq "a-z" ) { + $logger->trace( + "sentence BEGINS with lower-case letters (see oneSentencePerLine:sentencesBeginWith:a-z)") + if $is_t_switch_active; $sentencesBeginWithEachPart = qr/[a-z]/; - } elsif ($sentencesBeginWithEachPart eq "other"){ - $logger->trace("sentence BEGINS with other $yesNo (reg exp) (see oneSentencePerLine:sentencesBeginWith:other)") if $is_t_switch_active; + } + elsif ( $sentencesBeginWithEachPart eq "other" ) { + $logger->trace( + "sentence BEGINS with other $yesNo (reg exp) (see oneSentencePerLine:sentencesBeginWith:other)") + if $is_t_switch_active; $sentencesBeginWithEachPart = qr/$yesNo/; } - $sentencesBeginWith .= ($sentencesBeginWith eq "" ? q(): "|" ).$sentencesBeginWithEachPart; + $sentencesBeginWith .= ( $sentencesBeginWith eq "" ? q() : "|" ) . $sentencesBeginWithEachPart; } } $sentencesBeginWith = qr/$sentencesBeginWith/; @@ -118,28 +139,44 @@ sub one_sentence_per_line{ # sentences END with # sentences END with # sentences END with - ${${$mainSettings{modifyLineBreaks}{oneSentencePerLine}}{sentencesEndWith}}{basicFullStop} = 0 if ${${$mainSettings{modifyLineBreaks}{oneSentencePerLine}}{sentencesEndWith}}{betterFullStop}; + ${ ${ $mainSettings{modifyLineBreaks}{oneSentencePerLine} }{sentencesEndWith} }{basicFullStop} = 0 + if ${ ${ $mainSettings{modifyLineBreaks}{oneSentencePerLine} }{sentencesEndWith} }{betterFullStop}; my $sentencesEndWith = q(); - while( my ($sentencesEndWithEachPart,$yesNo)= each %{${$mainSettings{modifyLineBreaks}{oneSentencePerLine}}{sentencesEndWith}}){ - if($yesNo){ - if($sentencesEndWithEachPart eq "basicFullStop"){ - $logger->trace("sentence ENDS with full stop (see oneSentencePerLine:sentencesEndWith:basicFullStop") if $is_t_switch_active; + while ( my ( $sentencesEndWithEachPart, $yesNo ) + = each %{ ${ $mainSettings{modifyLineBreaks}{oneSentencePerLine} }{sentencesEndWith} } ) + { + if ($yesNo) { + if ( $sentencesEndWithEachPart eq "basicFullStop" ) { + $logger->trace("sentence ENDS with full stop (see oneSentencePerLine:sentencesEndWith:basicFullStop") + if $is_t_switch_active; $sentencesEndWithEachPart = qr/\./; - } elsif($sentencesEndWithEachPart eq "betterFullStop"){ - $logger->trace("sentence ENDS with *better* full stop (see oneSentencePerLine:sentencesEndWith:betterFullStop") if $is_t_switch_active; + } + elsif ( $sentencesEndWithEachPart eq "betterFullStop" ) { + $logger->trace( + "sentence ENDS with *better* full stop (see oneSentencePerLine:sentencesEndWith:betterFullStop") + if $is_t_switch_active; $sentencesEndWithEachPart = qr/${${$mainSettings{fineTuning}}{modifyLineBreaks}}{betterFullStop}/; - } elsif ($sentencesEndWithEachPart eq "exclamationMark"){ - $logger->trace("sentence ENDS with exclamation mark (see oneSentencePerLine:sentencesEndWith:exclamationMark)") if $is_t_switch_active; + } + elsif ( $sentencesEndWithEachPart eq "exclamationMark" ) { + $logger->trace( + "sentence ENDS with exclamation mark (see oneSentencePerLine:sentencesEndWith:exclamationMark)") + if $is_t_switch_active; $sentencesEndWithEachPart = qr/!/; - } elsif ($sentencesEndWithEachPart eq "questionMark"){ - $logger->trace("sentence ENDS with question mark (see oneSentencePerLine:sentencesEndWith:questionMark)") if $is_t_switch_active; + } + elsif ( $sentencesEndWithEachPart eq "questionMark" ) { + $logger->trace( + "sentence ENDS with question mark (see oneSentencePerLine:sentencesEndWith:questionMark)") + if $is_t_switch_active; $sentencesEndWithEachPart = qr/\?/; - } elsif ($sentencesEndWithEachPart eq "other"){ - $logger->trace("sentence ENDS with other $yesNo (reg exp) (see oneSentencePerLine:sentencesEndWith:other)") if $is_t_switch_active; + } + elsif ( $sentencesEndWithEachPart eq "other" ) { + $logger->trace( + "sentence ENDS with other $yesNo (reg exp) (see oneSentencePerLine:sentencesEndWith:other)") + if $is_t_switch_active; $sentencesEndWithEachPart = qr/$yesNo/; } - $sentencesEndWith .= ($sentencesEndWith eq "" ? q(): "|" ).$sentencesEndWithEachPart; + $sentencesEndWith .= ( $sentencesEndWith eq "" ? q() : "|" ) . $sentencesEndWithEachPart; } } $sentencesEndWith = qr/$sentencesEndWith/; @@ -154,7 +191,7 @@ sub one_sentence_per_line{ my $notWithinSentence = qr/$trailingCommentRegExp/s; - # if + # if # # modifyLineBreaks # oneSentencePerLine @@ -163,13 +200,13 @@ sub one_sentence_per_line{ # # is set to 0 then we need to *exclude* the $tokens{blanklines} from the sentence routine, # otherwise we could begin a sentence with $tokens{blanklines}. - if(!${${$mainSettings{modifyLineBreaks}{oneSentencePerLine}}{sentencesFollow}}{blankLine}){ - $notWithinSentence .= "|".qr/(?:\h*\R?$tokens{blanklines})/s; + if ( !${ ${ $mainSettings{modifyLineBreaks}{oneSentencePerLine} }{sentencesFollow} }{blankLine} ) { + $notWithinSentence .= "|" . qr/(?:\h*\R?$tokens{blanklines})/s; } # similarly for \par - if(${${$mainSettings{modifyLineBreaks}{oneSentencePerLine}}{sentencesFollow}}{par}){ - $notWithinSentence .= "|".qr/(?:\R?\\par)/s; + if ( ${ ${ $mainSettings{modifyLineBreaks}{oneSentencePerLine} }{sentencesFollow} }{par} ) { + $notWithinSentence .= "|" . qr/(?:\R?\\par)/s; } # initiate the sentence counter @@ -237,63 +274,74 @@ sub one_sentence_per_line{ $replacementText; /xsge; - if(${$mainSettings{modifyLineBreaks}{oneSentencePerLine}}{sentenceIndent} !~ m/\h+/){ - # loop back through the sentenceStorage and replace with the sentence, adjusting line breaks - # before and after appropriately - while( my $sentence = pop @sentenceStorage){ - my $sentenceStorageID = ${$sentence}{id}; - my $sentenceStorageValue = ${$sentence}{value}; - - # option to text wrap (and option to indent) sentences - if(${$mainSettings{modifyLineBreaks}{oneSentencePerLine}}{textWrapSentences}){ - my $sentenceObj = LatexIndent::Document->new(body=>$sentenceStorageValue, - name=>"sentence", - modifyLineBreaksYamlName=>"sentence", - ); - - # text wrapping - if(${$mainSettings{modifyLineBreaks}{textWrapOptions}}{columns}==0){ - $logger->warn("*Sentence text wrap warning:"); - $logger->info("You have specified oneSentencePerLine:textWrapSentences, but columns is set to 0"); - $logger->info("You might wish to specify, for example: modifyLineBreaks: textWrapOptions: columns: 80"); - $logger->info("The value of oneSentencePerLine:textWrapSentences will now be set to 0, so you won't see this message again"); - ${$mainSettings{modifyLineBreaks}{oneSentencePerLine}}{textWrapSentences} = 0; - } else { - $sentenceObj->text_wrap; - } - - # indentation of sentences - if(${$sentenceObj}{body} =~ m/ + if ( ${ $mainSettings{modifyLineBreaks}{oneSentencePerLine} }{sentenceIndent} !~ m/\h+/ ) { + + # loop back through the sentenceStorage and replace with the sentence, adjusting line breaks + # before and after appropriately + while ( my $sentence = pop @sentenceStorage ) { + my $sentenceStorageID = ${$sentence}{id}; + my $sentenceStorageValue = ${$sentence}{value}; + + # option to text wrap (and option to indent) sentences + if ( ${ $mainSettings{modifyLineBreaks}{oneSentencePerLine} }{textWrapSentences} ) { + my $sentenceObj = LatexIndent::Document->new( + body => $sentenceStorageValue, + name => "sentence", + modifyLineBreaksYamlName => "sentence", + ); + + # text wrapping + if ( ${ $mainSettings{modifyLineBreaks}{textWrapOptions} }{columns} == 0 ) { + $logger->warn("*Sentence text wrap warning:"); + $logger->info("You have specified oneSentencePerLine:textWrapSentences, but columns is set to 0"); + $logger->info( + "You might wish to specify, for example: modifyLineBreaks: textWrapOptions: columns: 80"); + $logger->info( + "The value of oneSentencePerLine:textWrapSentences will now be set to 0, so you won't see this message again" + ); + ${ $mainSettings{modifyLineBreaks}{oneSentencePerLine} }{textWrapSentences} = 0; + } + else { + $sentenceObj->text_wrap; + } + + # indentation of sentences + if (${$sentenceObj}{body} =~ m/ (.*?) # content of first line \R # first line break (.*$) # rest of body - /sx){ - my $bodyFirstLine = $1; - my $remainingBody = $2; - my $indentation = ${$mainSettings{modifyLineBreaks}{oneSentencePerLine}}{sentenceIndent}; - $logger->trace("first line of sencent: $bodyFirstLine") if $is_tt_switch_active; - $logger->trace("remaining body (before indentation):\n'$remainingBody'") if($is_tt_switch_active); - - # add the indentation to all the body except first line - $remainingBody =~ s/^/$indentation/mg unless($remainingBody eq ''); # add indentation - $logger->trace("remaining body (after indentation):\n$remainingBody'") if($is_tt_switch_active); - - # put the body back together - ${$sentenceObj}{body} = $bodyFirstLine."\n".$remainingBody; - } - $sentenceStorageValue = ${$sentenceObj}{body}; - }; - # sentence at the very END - ${$self}{body} =~ s/\h*$sentenceStorageID\h*$/$sentenceStorageValue/s; - # sentence at the very BEGINNING - ${$self}{body} =~ s/^$sentenceStorageID\h*\R?/$sentenceStorageValue\n/s; - # all other sentences - ${$self}{body} =~ s/\R?\h*$sentenceStorageID\h*\R?/\n$sentenceStorageValue\n/s; - } - } + /sx + ) + { + my $bodyFirstLine = $1; + my $remainingBody = $2; + my $indentation = ${ $mainSettings{modifyLineBreaks}{oneSentencePerLine} }{sentenceIndent}; + $logger->trace("first line of sencent: $bodyFirstLine") if $is_tt_switch_active; + $logger->trace("remaining body (before indentation):\n'$remainingBody'") if ($is_tt_switch_active); + + # add the indentation to all the body except first line + $remainingBody =~ s/^/$indentation/mg unless ( $remainingBody eq '' ); # add indentation + $logger->trace("remaining body (after indentation):\n$remainingBody'") if ($is_tt_switch_active); + + # put the body back together + ${$sentenceObj}{body} = $bodyFirstLine . "\n" . $remainingBody; + } + $sentenceStorageValue = ${$sentenceObj}{body}; + } + + # sentence at the very END + ${$self}{body} =~ s/\h*$sentenceStorageID\h*$/$sentenceStorageValue/s; + + # sentence at the very BEGINNING + ${$self}{body} =~ s/^$sentenceStorageID\h*\R?/$sentenceStorageValue\n/s; + + # all other sentences + ${$self}{body} =~ s/\R?\h*$sentenceStorageID\h*\R?/\n$sentenceStorageValue\n/s; + } + } } -sub create_unique_id{ +sub create_unique_id { my $self = shift; $sentenceCounter++; @@ -301,69 +349,73 @@ sub create_unique_id{ return; } -sub tasks_particular_to_each_object{ - my $self = shift; +sub tasks_particular_to_each_object { + my $self = shift; - # option to text wrap (and option to indent) sentences - if(${$mainSettings{modifyLineBreaks}{oneSentencePerLine}}{textWrapSentences} - and ${$mainSettings{modifyLineBreaks}{textWrapOptions}}{columns} !=0 ){ + # option to text wrap (and option to indent) sentences + if ( ${ $mainSettings{modifyLineBreaks}{oneSentencePerLine} }{textWrapSentences} + and ${ $mainSettings{modifyLineBreaks}{textWrapOptions} }{columns} != 0 ) + { $self->text_wrap; - } - - # search for environments - $logger->trace('looking for ENVIRONMENTS') if $is_t_switch_active; - $self->find_environments if ${$self}{body} =~ m/$environmentBasicRegExp/s; - - # search for ifElseFi blocks - $logger->trace('looking for IFELSEFI') if $is_t_switch_active; - $self->find_ifelsefi if ${$self}{body} =~ m/$ifElseFiBasicRegExp/s; - - # search for headings (part, chapter, section, setc) - $logger->trace('looking for HEADINGS (chapter, section, part, etc)') if $is_t_switch_active; - $self->find_heading if ${$self}{body} =~ m/$allHeadingsRegexp/s; - - # the ordering of finding commands and special code blocks can change - $self->find_commands_or_key_equals_values_braces_and_special if ${$self}{body} =~ m/$specialBeginAndBracesBracketsBasicRegExp/s; + } + + # search for environments + $logger->trace('looking for ENVIRONMENTS') if $is_t_switch_active; + $self->find_environments if ${$self}{body} =~ m/$environmentBasicRegExp/s; + + # search for ifElseFi blocks + $logger->trace('looking for IFELSEFI') if $is_t_switch_active; + $self->find_ifelsefi if ${$self}{body} =~ m/$ifElseFiBasicRegExp/s; + + # search for headings (part, chapter, section, setc) + $logger->trace('looking for HEADINGS (chapter, section, part, etc)') if $is_t_switch_active; + $self->find_heading if ${$self}{body} =~ m/$allHeadingsRegexp/s; + + # the ordering of finding commands and special code blocks can change + $self->find_commands_or_key_equals_values_braces_and_special + if ${$self}{body} =~ m/$specialBeginAndBracesBracketsBasicRegExp/s; } -sub indent_body{ - return unless ${$mainSettings{modifyLineBreaks}{oneSentencePerLine}}{sentenceIndent} =~ m/\h+/; +sub indent_body { + return unless ${ $mainSettings{modifyLineBreaks}{oneSentencePerLine} }{sentenceIndent} =~ m/\h+/; - my $self = shift; + my $self = shift; - # indentation of sentences - if(${$self}{body} =~ m/ + # indentation of sentences + if (${$self}{body} =~ m/ (.*?) # content of first line \R # first line break (.*$) # rest of body - /sx){ - my $bodyFirstLine = $1; - my $remainingBody = $2; - my $indentation = ${$self}{indentation}; - $logger->trace("first line of sentence $bodyFirstLine") if $is_tt_switch_active; - $logger->trace("remaining body (before indentation):\n'$remainingBody'") if($is_tt_switch_active); - - # add the indentation to all the body except first line - $remainingBody =~ s/^/$indentation/mg unless($remainingBody eq ''); # add indentation - $logger->trace("remaining body (after indentation):\n$remainingBody'") if($is_tt_switch_active); - - # put the body back together - ${$self}{body} = $bodyFirstLine."\n".$remainingBody; - } + /sx + ) + { + my $bodyFirstLine = $1; + my $remainingBody = $2; + my $indentation = ${$self}{indentation}; + $logger->trace("first line of sentence $bodyFirstLine") if $is_tt_switch_active; + $logger->trace("remaining body (before indentation):\n'$remainingBody'") if ($is_tt_switch_active); + + # add the indentation to all the body except first line + $remainingBody =~ s/^/$indentation/mg unless ( $remainingBody eq '' ); # add indentation + $logger->trace("remaining body (after indentation):\n$remainingBody'") if ($is_tt_switch_active); + + # put the body back together + ${$self}{body} = $bodyFirstLine . "\n" . $remainingBody; + } } -sub yaml_get_indentation_settings_for_this_object{ - return; +sub yaml_get_indentation_settings_for_this_object { + return; } -sub add_surrounding_indentation_to_begin_statement{ +sub add_surrounding_indentation_to_begin_statement { + # specific method for sentences my $self = shift; my $surroundingIndentation = ${$self}{surroundingIndentation}; - ${$self}{body} =~ s/^(\h*)?/$surroundingIndentation/s; # add indentation + ${$self}{body} =~ s/^(\h*)?/$surroundingIndentation/s; # add indentation } - 1; diff --git a/Master/texmf-dist/scripts/latexindent/LatexIndent/Special.pm b/Master/texmf-dist/scripts/latexindent/LatexIndent/Special.pm index 8d7346324da..331d5e87cf9 100644 --- a/Master/texmf-dist/scripts/latexindent/LatexIndent/Special.pm +++ b/Master/texmf-dist/scripts/latexindent/LatexIndent/Special.pm @@ -1,4 +1,5 @@ package LatexIndent::Special; + # 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 @@ -24,50 +25,54 @@ use LatexIndent::LogFile qw/$logger/; use LatexIndent::IfElseFi qw/$ifElseFiBasicRegExp/; use Data::Dumper; use Exporter qw/import/; -our @ISA = "LatexIndent::Document"; # class inheritance, Programming Perl, pg 321 -our @EXPORT_OK = qw/find_special construct_special_begin $specialBeginAndBracesBracketsBasicRegExp $specialBeginBasicRegExp/; +our @ISA = "LatexIndent::Document"; # class inheritance, Programming Perl, pg 321 +our @EXPORT_OK + = qw/find_special construct_special_begin $specialBeginAndBracesBracketsBasicRegExp $specialBeginBasicRegExp/; our $specialCounter; -our $specialBegins = q(); +our $specialBegins = q(); our $specialAllMatchesRegExp = q(); our %individualSpecialRegExps; our $specialBeginAndBracesBracketsBasicRegExp; our $specialBeginBasicRegExp; -sub construct_special_begin{ +sub construct_special_begin { my $self = shift; $logger->trace("*Constructing specialBeginEnd regex (see specialBeginEnd)") if $is_t_switch_active; # put together a list of the begin terms in special - while( my ($specialName,$BeginEnd)= each %{$mainSettings{specialBeginEnd}}){ - if(ref($BeginEnd) eq "HASH"){ - if (not defined ${$BeginEnd}{lookForThis}){ - ${$BeginEnd}{lookForThis} = 1; - ${${$mainSettings{specialBeginEnd}}{$specialName}}{lookForThis} = 1; - $logger->trace("setting lookForThis:1 for $specialName (lookForThis not specified)") if $is_t_switch_active; - } + while ( my ( $specialName, $BeginEnd ) = each %{ $mainSettings{specialBeginEnd} } ) { + if ( ref($BeginEnd) eq "HASH" ) { + if ( not defined ${$BeginEnd}{lookForThis} ) { + ${$BeginEnd}{lookForThis} = 1; + ${ ${ $mainSettings{specialBeginEnd} }{$specialName} }{lookForThis} = 1; + $logger->trace("setting lookForThis:1 for $specialName (lookForThis not specified)") + if $is_t_switch_active; + } - # only append the regexps if lookForThis is 1 - $specialBegins .= ($specialBegins eq ""?q():"|").${$BeginEnd}{begin} if(${$BeginEnd}{lookForThis}=~m/\d/s and ${$BeginEnd}{lookForThis} == 1); - } + # only append the regexps if lookForThis is 1 + $specialBegins .= ( $specialBegins eq "" ? q() : "|" ) . ${$BeginEnd}{begin} + if ( ${$BeginEnd}{lookForThis} =~ m/\d/s and ${$BeginEnd}{lookForThis} == 1 ); + } } # put together a list of the begin terms in special - while( my ($specialName,$BeginEnd)= each %{$mainSettings{specialBeginEnd}}){ + while ( my ( $specialName, $BeginEnd ) = each %{ $mainSettings{specialBeginEnd} } ) { - # only append the regexps if lookForThis is 1 - if( ref($BeginEnd) eq "HASH" ){ - if ( ${$BeginEnd}{lookForThis}=~m/\d/s and ${$BeginEnd}{lookForThis} == 0 ){ - $logger->trace("The specialBeginEnd regexps won't include anything from $specialName (lookForThis: 0)") if $is_t_switch_active ; + # only append the regexps if lookForThis is 1 + if ( ref($BeginEnd) eq "HASH" ) { + if ( ${$BeginEnd}{lookForThis} =~ m/\d/s and ${$BeginEnd}{lookForThis} == 0 ) { + $logger->trace("The specialBeginEnd regexps won't include anything from $specialName (lookForThis: 0)") + if $is_t_switch_active; + next; + } + } + else { next; } - } else { - next; - } - # the overall regexp - $specialAllMatchesRegExp .= ($specialAllMatchesRegExp eq ""?q():"|") - .qr/ + # the overall regexp + $specialAllMatchesRegExp .= ( $specialAllMatchesRegExp eq "" ? q() : "|" ) . qr/ ${$BeginEnd}{begin} (?: # cluster-only (), don't capture (?! @@ -77,8 +82,8 @@ sub construct_special_begin{ ${$BeginEnd}{end} /sx; - # store the individual special regexp - $individualSpecialRegExps{$specialName} = qr/ + # store the individual special regexp + $individualSpecialRegExps{$specialName} = qr/ ( ${$BeginEnd}{begin} \h* @@ -102,54 +107,59 @@ sub construct_special_begin{ } # move $$ to the beginning - if($specialBegins =~ m/\|\\\$\\\$/){ - $specialBegins =~ s/\|(\\\$\\\$)//; - $specialBegins = $1."|".$specialBegins; + if ( $specialBegins =~ m/\|\\\$\\\$/ ) { + $specialBegins =~ s/\|(\\\$\\\$)//; + $specialBegins = $1 . "|" . $specialBegins; } # info to the log file $logger->trace("*The special beginnings regexp is: (see specialBeginEnd)") if $is_tt_switch_active; - $logger->trace($specialBegins) if $is_tt_switch_active; + $logger->trace($specialBegins) if $is_tt_switch_active; # overall special regexp $logger->trace("*The overall special regexp is: (see specialBeginEnd)") if $is_tt_switch_active; $logger->trace($specialAllMatchesRegExp) if $is_tt_switch_active; # basic special begin regexp - $specialBeginBasicRegExp = qr/$specialBegins/; - $specialBeginAndBracesBracketsBasicRegExp = $specialBegins."|\\{|\\["; + $specialBeginBasicRegExp = qr/$specialBegins/; + $specialBeginAndBracesBracketsBasicRegExp = $specialBegins . "|\\{|\\["; $specialBeginAndBracesBracketsBasicRegExp = qr/$specialBeginAndBracesBracketsBasicRegExp/; - } +} -sub find_special{ +sub find_special { my $self = shift; # no point carrying on if the list of specials is empty - return if($specialBegins eq ""); + return if ( $specialBegins eq "" ); # otherwise loop through the special begin/end - $logger->trace("*Searching ${$self}{name} for special begin/end (see specialBeginEnd)") if $is_t_switch_active ; - $logger->trace(Dumper(\%{$mainSettings{specialBeginEnd}})) if $is_tt_switch_active; + $logger->trace("*Searching ${$self}{name} for special begin/end (see specialBeginEnd)") if $is_t_switch_active; + $logger->trace( Dumper( \%{ $mainSettings{specialBeginEnd} } ) ) if $is_tt_switch_active; # keep looping as long as there is a special match of some kind - while(${$self}{body} =~ m/$specialAllMatchesRegExp/sx){ + while ( ${$self}{body} =~ m/$specialAllMatchesRegExp/sx ) { # loop through each special match - while( my ($specialName,$BeginEnd)= each %{$mainSettings{specialBeginEnd}}){ + while ( my ( $specialName, $BeginEnd ) = each %{ $mainSettings{specialBeginEnd} } ) { # log file - if((ref($BeginEnd) eq "HASH") and ${$BeginEnd}{lookForThis}=~m/\d/s and ${$BeginEnd}{lookForThis} == 1){ - $logger->trace("Looking for $specialName") if $is_t_switch_active ; - } else { - $logger->trace("Not looking for $specialName (see lookForThis)") if ($is_t_switch_active and (ref($BeginEnd) eq "HASH")); + if ( ( ref($BeginEnd) eq "HASH" ) + and ${$BeginEnd}{lookForThis} =~ m/\d/s + and ${$BeginEnd}{lookForThis} == 1 ) + { + $logger->trace("Looking for $specialName") if $is_t_switch_active; + } + else { + $logger->trace("Not looking for $specialName (see lookForThis)") + if ( $is_t_switch_active and ( ref($BeginEnd) eq "HASH" ) ); next; } # the regexp my $specialRegExp = $individualSpecialRegExps{$specialName}; - $logger->trace("$specialName regexp: \n$specialRegExp") if $is_tt_switch_active ; - - while(${$self}{body} =~ m/$specialRegExp(\h*)($trailingCommentRegExp)?/){ + $logger->trace("$specialName regexp: \n$specialRegExp") if $is_tt_switch_active; + + while ( ${$self}{body} =~ m/$specialRegExp(\h*)($trailingCommentRegExp)?/ ) { # global substitution ${$self}{body} =~ s/ @@ -190,65 +200,73 @@ sub find_special{ $self->wrap_up_tasks; } - } - } + } + } } -sub tasks_particular_to_each_object{ +sub tasks_particular_to_each_object { my $self = shift; - if( defined ${${$mainSettings{specialBeginEnd}}{${$self}{name}}}{middle}){ - $logger->trace("middle specified for ${$self}{name} (see specialBeginEnd -> ${$self}{name} -> middle)") if $is_t_switch_active ; - - # initiate the middle regexp - my $specialMiddle = q(); - - # we can specify middle as either an array or a hash - if(ref(${${$mainSettings{specialBeginEnd}}{${$self}{name}}}{middle}) eq "ARRAY"){ - $logger->trace("looping through middle array for ${$self}{name}") if $is_t_switch_active ; - foreach(@{${${$mainSettings{specialBeginEnd}}{${$self}{name}}}{middle}}){ - $specialMiddle .= ($specialMiddle eq ""?q():"|").$_; - } - $specialMiddle = qr/$specialMiddle/; - } else { - $specialMiddle = qr/${${$mainSettings{specialBeginEnd}}{${$self}{name}}}{middle}/; + if ( defined ${ ${ $mainSettings{specialBeginEnd} }{ ${$self}{name} } }{middle} ) { + $logger->trace("middle specified for ${$self}{name} (see specialBeginEnd -> ${$self}{name} -> middle)") + if $is_t_switch_active; + + # initiate the middle regexp + my $specialMiddle = q(); + + # we can specify middle as either an array or a hash + if ( ref( ${ ${ $mainSettings{specialBeginEnd} }{ ${$self}{name} } }{middle} ) eq "ARRAY" ) { + $logger->trace("looping through middle array for ${$self}{name}") if $is_t_switch_active; + foreach ( @{ ${ ${ $mainSettings{specialBeginEnd} }{ ${$self}{name} } }{middle} } ) { + $specialMiddle .= ( $specialMiddle eq "" ? q() : "|" ) . $_; } + $specialMiddle = qr/$specialMiddle/; + } + else { + $specialMiddle = qr/${${$mainSettings{specialBeginEnd}}{${$self}{name}}}{middle}/; + } + + $logger->trace("overall middle regexp for ${$self}{name}: $specialMiddle") if $is_t_switch_active; + + # store the middle regexp for later + ${$self}{middleRegExp} = $specialMiddle; + + # check for existence of a 'middle' statement, and associated line break information + $self->check_for_else_statement( + + # else name regexp + elseNameRegExp => $specialMiddle, + + # else statements name + ElseStartsOnOwnLine => "SpecialMiddleStartsOnOwnLine", + + # end statements + ElseFinishesWithLineBreak => "SpecialMiddleFinishesWithLineBreak", + + # for the YAML settings storage + storageNameAppend => "middle", + + # logfile information + logName => "special middle", + ); - $logger->trace("overall middle regexp for ${$self}{name}: $specialMiddle") if $is_t_switch_active ; - - # store the middle regexp for later - ${$self}{middleRegExp} = $specialMiddle; - - # check for existence of a 'middle' statement, and associated line break information - $self->check_for_else_statement( - # else name regexp - elseNameRegExp=>$specialMiddle, - # else statements name - ElseStartsOnOwnLine=>"SpecialMiddleStartsOnOwnLine", - # end statements - ElseFinishesWithLineBreak=>"SpecialMiddleFinishesWithLineBreak", - # for the YAML settings storage - storageNameAppend=>"middle", - # logfile information - logName=>"special middle", - ); - - } - return unless(${$mainSettings{specialBeginEnd}}{specialBeforeCommand}); + return unless ( ${ $mainSettings{specialBeginEnd} }{specialBeforeCommand} ); # lookForAlignDelims: lookForChildCodeBlocks set to 0 means no child objects searched for # see: test-cases/alignment/issue-308-special.tex # - if( defined ${$self}{lookForChildCodeBlocks} and !${$self}{lookForChildCodeBlocks} ){ - $logger->trace("lookForAlignDelims: lookForChildCodeBlocks set to 0, so child objects will *NOT* be searched for") if($is_t_switch_active); - return; + if ( defined ${$self}{lookForChildCodeBlocks} and !${$self}{lookForChildCodeBlocks} ) { + $logger->trace( + "lookForAlignDelims: lookForChildCodeBlocks set to 0, so child objects will *NOT* be searched for") + if ($is_t_switch_active); + return; } # search for commands with arguments $self->find_commands_or_key_equals_values_braces; - + # search for arguments $self->find_opt_mand_arguments; @@ -257,30 +275,31 @@ sub tasks_particular_to_each_object{ } -sub post_indentation_check{ +sub post_indentation_check { + # needed to remove leading horizontal space before \else my $self = shift; - return unless ( defined ${${$mainSettings{specialBeginEnd}}{${$self}{name}}}{middle}); + return unless ( defined ${ ${ $mainSettings{specialBeginEnd} }{ ${$self}{name} } }{middle} ); - $logger->trace("post indentation check for ${$self}{name} to account for middle") if $is_t_switch_active ; + $logger->trace("post indentation check for ${$self}{name} to account for middle") if $is_t_switch_active; # loop through \else and \or - foreach ({regExp=>${$self}{middleRegExp}}){ + foreach ( { regExp => ${$self}{middleRegExp} } ) { my %else = %{$_}; - if(${$self}{body} =~ m/^\h*$else{regExp}/sm - and - !(${$self}{body} =~ m/^\h*$else{regExp}/s and ${$self}{linebreaksAtEnd}{begin}==0) - ){ - $logger->trace("*Adding surrounding indentation to $else{regExp} statement(s) ('${$self}{surroundingIndentation}')") if $is_t_switch_active; + if ( ${$self}{body} =~ m/^\h*$else{regExp}/sm + and !( ${$self}{body} =~ m/^\h*$else{regExp}/s and ${$self}{linebreaksAtEnd}{begin} == 0 ) ) + { + $logger->trace( + "*Adding surrounding indentation to $else{regExp} statement(s) ('${$self}{surroundingIndentation}')") + if $is_t_switch_active; ${$self}{body} =~ s/^\h*($else{regExp})/${$self}{surroundingIndentation}$1/smg; } } return; } - -sub create_unique_id{ +sub create_unique_id { my $self = shift; $specialCounter++; diff --git a/Master/texmf-dist/scripts/latexindent/LatexIndent/Switches.pm b/Master/texmf-dist/scripts/latexindent/LatexIndent/Switches.pm index a57722782b2..858e3519137 100644 --- a/Master/texmf-dist/scripts/latexindent/LatexIndent/Switches.pm +++ b/Master/texmf-dist/scripts/latexindent/LatexIndent/Switches.pm @@ -1,4 +1,5 @@ package LatexIndent::Switches; + # 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 @@ -17,7 +18,8 @@ package LatexIndent::Switches; use strict; use warnings; use Exporter qw/import/; -our @EXPORT_OK = qw/%switches store_switches $is_m_switch_active $is_t_switch_active $is_tt_switch_active $is_r_switch_active $is_rr_switch_active $is_rv_switch_active $is_check_switch_active $is_check_verbose_switch_active/; +our @EXPORT_OK + = qw/%switches store_switches $is_m_switch_active $is_t_switch_active $is_tt_switch_active $is_r_switch_active $is_rr_switch_active $is_rv_switch_active $is_check_switch_active $is_check_verbose_switch_active/; our %switches; our $is_m_switch_active; our $is_t_switch_active; @@ -28,23 +30,27 @@ our $is_rv_switch_active; our $is_check_switch_active; our $is_check_verbose_switch_active; -sub store_switches{ +sub store_switches { my $self = shift; # copy document switches into hash local to this module - %switches = %{${$self}{switches}}; - $switches{version} = defined $switches{vversion} ? 1 : $switches{version}; - $is_m_switch_active = defined $switches{modifyLineBreaks}?$switches{modifyLineBreaks}: 0; - $is_t_switch_active = defined $switches{trace}?$switches{trace}: 0; - $is_tt_switch_active = defined $switches{ttrace}?$switches{ttrace}: 0; - $is_t_switch_active = $is_tt_switch_active ? $is_tt_switch_active : $is_t_switch_active; - $is_r_switch_active = defined $switches{replacement}?$switches{replacement}: 0; - $is_rr_switch_active = defined $switches{onlyreplacement}?$switches{onlyreplacement}: 0; - $is_rv_switch_active = defined $switches{replacementRespectVerb}?$switches{replacementRespectVerb}: 0; - $is_r_switch_active = ($is_rr_switch_active|$is_rv_switch_active) ? ($is_rr_switch_active|$is_rv_switch_active) : $is_r_switch_active; - $is_check_switch_active = defined $switches{check}?$switches{check}: 0; - $is_check_verbose_switch_active = defined $switches{checkverbose}?$switches{checkverbose}: 0; - $is_check_switch_active = $is_check_verbose_switch_active ? $is_check_verbose_switch_active : $is_check_switch_active; + %switches = %{ ${$self}{switches} }; + $switches{version} = defined $switches{vversion} ? 1 : $switches{version}; + $is_m_switch_active = defined $switches{modifyLineBreaks} ? $switches{modifyLineBreaks} : 0; + $is_t_switch_active = defined $switches{trace} ? $switches{trace} : 0; + $is_tt_switch_active = defined $switches{ttrace} ? $switches{ttrace} : 0; + $is_t_switch_active = $is_tt_switch_active ? $is_tt_switch_active : $is_t_switch_active; + $is_r_switch_active = defined $switches{replacement} ? $switches{replacement} : 0; + $is_rr_switch_active = defined $switches{onlyreplacement} ? $switches{onlyreplacement} : 0; + $is_rv_switch_active = defined $switches{replacementRespectVerb} ? $switches{replacementRespectVerb} : 0; + $is_r_switch_active + = ( $is_rr_switch_active | $is_rv_switch_active ) + ? ( $is_rr_switch_active | $is_rv_switch_active ) + : $is_r_switch_active; + $is_check_switch_active = defined $switches{check} ? $switches{check} : 0; + $is_check_verbose_switch_active = defined $switches{checkverbose} ? $switches{checkverbose} : 0; + $is_check_switch_active + = $is_check_verbose_switch_active ? $is_check_verbose_switch_active : $is_check_switch_active; delete ${$self}{switches}; - } +} 1; diff --git a/Master/texmf-dist/scripts/latexindent/LatexIndent/Tokens.pm b/Master/texmf-dist/scripts/latexindent/LatexIndent/Tokens.pm index 98926a97594..adea6481abc 100644 --- a/Master/texmf-dist/scripts/latexindent/LatexIndent/Tokens.pm +++ b/Master/texmf-dist/scripts/latexindent/LatexIndent/Tokens.pm @@ -1,4 +1,5 @@ package LatexIndent::Tokens; + # 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 @@ -22,54 +23,57 @@ use LatexIndent::LogFile qw/$logger/; our @EXPORT_OK = qw/token_check %tokens/; # each of the tokens begins the same way -- this is exploited during the hidden Children routine -my $beginningToken = "LTXIN-TK-"; +my $beginningToken = "LTXIN-TK-"; my $ifelsefiSpecial = "!-!"; # the %tokens hash is passed around many modules our %tokens = ( - # user-facing naming convention - environments=>$beginningToken."ENVIRONMENT", - commands=>$beginningToken."COMMAND", - optionalArguments=>$beginningToken."OPTIONAL-ARGUMENT", - mandatoryArguments=>$beginningToken."MANDATORY-ARGUMENT", - ifElseFi=>$ifelsefiSpecial.$beginningToken."IFELSEFI", - else=>$beginningToken."ELSE", - items=>$beginningToken."ITEMS", - keyEqualsValuesBracesBrackets=>$beginningToken."KEY-VALUE-BRACES", - namedGroupingBracesBrackets=>$beginningToken."GROUPING-BRACES", - UnNamedGroupingBracesBrackets=>$beginningToken."UN-NAMED-GROUPING-BRACES", - specialBeginEnd=>$beginningToken."SPECIAL", - afterHeading=>$beginningToken."HEADING", - filecontents=>$beginningToken."FILECONTENTS", - # internal-facing naming convention - trailingComment=>"latexindenttrailingcomment", - ifelsefiSpecial=>$ifelsefiSpecial, - blanklines=>$beginningToken."blank-line", - arguments=>$beginningToken."ARGUMENTS", - roundBracket=>$beginningToken."ROUND-BRACKET", - verbatim=>$beginningToken."VERBATIM", - verbatimInline=>$beginningToken."VERBATIM-inline", - preamble=>$beginningToken."preamble", - beginOfToken=>$beginningToken, - doubleBackSlash=>$beginningToken."DOUBLEBACKSLASH", - alignmentBlock=>$beginningToken."ALIGNMENTBLOCK", - paragraph=>$beginningToken."PARA", - sentence=>$beginningToken."SENTENCE", - endOfToken=>"-END", - ); -sub token_check{ + # user-facing naming convention + environments => $beginningToken . "ENVIRONMENT", + commands => $beginningToken . "COMMAND", + optionalArguments => $beginningToken . "OPTIONAL-ARGUMENT", + mandatoryArguments => $beginningToken . "MANDATORY-ARGUMENT", + ifElseFi => $ifelsefiSpecial . $beginningToken . "IFELSEFI", + else => $beginningToken . "ELSE", + items => $beginningToken . "ITEMS", + keyEqualsValuesBracesBrackets => $beginningToken . "KEY-VALUE-BRACES", + namedGroupingBracesBrackets => $beginningToken . "GROUPING-BRACES", + UnNamedGroupingBracesBrackets => $beginningToken . "UN-NAMED-GROUPING-BRACES", + specialBeginEnd => $beginningToken . "SPECIAL", + afterHeading => $beginningToken . "HEADING", + filecontents => $beginningToken . "FILECONTENTS", + + # internal-facing naming convention + trailingComment => "latexindenttrailingcomment", + ifelsefiSpecial => $ifelsefiSpecial, + blanklines => $beginningToken . "blank-line", + arguments => $beginningToken . "ARGUMENTS", + roundBracket => $beginningToken . "ROUND-BRACKET", + verbatim => $beginningToken . "VERBATIM", + verbatimInline => $beginningToken . "VERBATIM-inline", + preamble => $beginningToken . "preamble", + beginOfToken => $beginningToken, + doubleBackSlash => $beginningToken . "DOUBLEBACKSLASH", + alignmentBlock => $beginningToken . "ALIGNMENTBLOCK", + paragraph => $beginningToken . "PARA", + sentence => $beginningToken . "SENTENCE", + endOfToken => "-END", +); + +sub token_check { my $self = shift; $logger->trace("*Token check") if $is_t_switch_active; + # we use tokens for trailing comments, environments, commands, etc, so check that they're not in the body - foreach( keys %tokens){ - while(${$self}{body} =~ m/$tokens{$_}/si){ - $logger->trace("Found $tokens{$_} within body, updating replacement token to $tokens{$_}-LIN") if($is_t_switch_active); + foreach ( keys %tokens ) { + while ( ${$self}{body} =~ m/$tokens{$_}/si ) { + $logger->trace("Found $tokens{$_} within body, updating replacement token to $tokens{$_}-LIN") + if ($is_t_switch_active); $tokens{$_} .= "-LIN"; } } } - 1; diff --git a/Master/texmf-dist/scripts/latexindent/LatexIndent/TrailingComments.pm b/Master/texmf-dist/scripts/latexindent/LatexIndent/TrailingComments.pm index 8bab5bc1308..4ddfe8eb1aa 100644 --- a/Master/texmf-dist/scripts/latexindent/LatexIndent/TrailingComments.pm +++ b/Master/texmf-dist/scripts/latexindent/LatexIndent/TrailingComments.pm @@ -1,4 +1,5 @@ package LatexIndent::TrailingComments; + # 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 @@ -22,18 +23,20 @@ use LatexIndent::GetYamlSettings qw/%mainSettings/; use LatexIndent::LogFile qw/$logger/; use Data::Dumper; use Exporter qw/import/; -our @EXPORT_OK = qw/remove_trailing_comments put_trailing_comments_back_in $trailingCommentRegExp add_comment_symbol construct_trailing_comment_regexp/; +our @EXPORT_OK + = qw/remove_trailing_comments put_trailing_comments_back_in $trailingCommentRegExp add_comment_symbol construct_trailing_comment_regexp/; our @trailingComments; our $commentCounter = 0; our $trailingCommentRegExp; -sub construct_trailing_comment_regexp{ - my $notPreceededBy = qr/${${$mainSettings{fineTuning}}{trailingComments}}{notPreceededBy}/; +sub construct_trailing_comment_regexp { + my $notPreceededBy = qr/${${$mainSettings{fineTuning}}{trailingComments}}{notPreceededBy}/; $trailingCommentRegExp = qr/$notPreceededBy%$tokens{trailingComment}\d+$tokens{endOfToken}/; } -sub add_comment_symbol{ +sub add_comment_symbol { + # add a trailing comment token after, for example, a square brace [ # or a curly brace { when, for example, BeginStartsOnOwnLine == 2 my $self = shift; @@ -42,24 +45,24 @@ sub add_comment_symbol{ $commentCounter++; # store the comment -- without this, it won't get processed correctly at the end - push(@trailingComments,{id=>$tokens{trailingComment}.$commentCounter.$tokens{endOfToken},value=>q()}); + push( @trailingComments, { id => $tokens{trailingComment} . $commentCounter . $tokens{endOfToken}, value => q() } ); # log file info - $logger->trace("*Updating trailing comment array")if $is_t_switch_active; - $logger->trace(Dumper(\@trailingComments),'ttrace') if($is_tt_switch_active); + $logger->trace("*Updating trailing comment array") if $is_t_switch_active; + $logger->trace( Dumper( \@trailingComments ), 'ttrace' ) if ($is_tt_switch_active); # the returned value - return $tokens{trailingComment}.$commentCounter.$tokens{endOfToken}; + return $tokens{trailingComment} . $commentCounter . $tokens{endOfToken}; } -sub remove_trailing_comments{ +sub remove_trailing_comments { my $self = shift; $commentCounter = 0; - $logger->trace("*Storing trailing comments")if $is_t_switch_active; + $logger->trace("*Storing trailing comments") if $is_t_switch_active; - my $notPreceededBy = qr/${${$mainSettings{fineTuning}}{trailingComments}}{notPreceededBy}/; + my $notPreceededBy = qr/${${$mainSettings{fineTuning}}{trailingComments}}{notPreceededBy}/; # perform the substitution ${$self}{body} =~ s/ @@ -78,49 +81,57 @@ sub remove_trailing_comments{ # replace comment with dummy text "%".$tokens{trailingComment}.$commentCounter.$tokens{endOfToken}; /xsmeg; - if(@trailingComments){ - $logger->trace("Trailing comments stored in:") if($is_tt_switch_active); - $logger->trace(Dumper(\@trailingComments)) if($is_tt_switch_active); - } else { - $logger->trace("No trailing comments found") if($is_t_switch_active); + if (@trailingComments) { + $logger->trace("Trailing comments stored in:") if ($is_tt_switch_active); + $logger->trace( Dumper( \@trailingComments ) ) if ($is_tt_switch_active); + } + else { + $logger->trace("No trailing comments found") if ($is_t_switch_active); } return; } -sub put_trailing_comments_back_in{ +sub put_trailing_comments_back_in { my $self = shift; - return unless( @trailingComments > 0 ); + return unless ( @trailingComments > 0 ); - $logger->trace("*Returning trailing comments to body")if $is_t_switch_active; + $logger->trace("*Returning trailing comments to body") if $is_t_switch_active; - # loop through trailing comments in reverse so that, for example, - # latexindenttrailingcomment1 doesn't match the first + # loop through trailing comments in reverse so that, for example, + # latexindenttrailingcomment1 doesn't match the first # part of latexindenttrailingcomment18, which would result in an 8 left over (bad) - while( my $comment = pop @trailingComments){ - my $trailingcommentID = ${$comment}{id}; - my $trailingcommentValue = ${$comment}{value}; - - # the -m switch can modify max characters per line, and trailing comment IDs can - # be split across lines - if($is_m_switch_active - and ${$mainSettings{modifyLineBreaks}{textWrapOptions}}{huge} ne "overflow" - and ${$self}{body} !~ m/%$trailingcommentID/m){ - $logger->trace("$trailingcommentID not found in body using /m matching, assuming it has been split across line (see modifyLineBreaks: textWrapOptions)") if($is_t_switch_active); + while ( my $comment = pop @trailingComments ) { + my $trailingcommentID = ${$comment}{id}; + my $trailingcommentValue = ${$comment}{value}; + + # the -m switch can modify max characters per line, and trailing comment IDs can + # be split across lines + if ( $is_m_switch_active + and ${ $mainSettings{modifyLineBreaks}{textWrapOptions} }{huge} ne "overflow" + and ${$self}{body} !~ m/%$trailingcommentID/m ) + { + $logger->trace( + "$trailingcommentID not found in body using /m matching, assuming it has been split across line (see modifyLineBreaks: textWrapOptions)" + ) if ($is_t_switch_active); my $trailingcommentIDwithLineBreaks; - + # construct a reg exp that contains possible line breaks in between each character - if(${$mainSettings{modifyLineBreaks}{textWrapOptions}}{separator} ne ''){ - $trailingcommentIDwithLineBreaks = join("\\".${$mainSettings{modifyLineBreaks}{textWrapOptions}}{separator}."?",split(//,$trailingcommentID)); - } else { - $trailingcommentIDwithLineBreaks = join("(?:\\h|\\R)*",split(//,$trailingcommentID)); + if ( ${ $mainSettings{modifyLineBreaks}{textWrapOptions} }{separator} ne '' ) { + $trailingcommentIDwithLineBreaks = join( + "\\" . ${ $mainSettings{modifyLineBreaks}{textWrapOptions} }{separator} . "?", + split( //, $trailingcommentID ) + ); + } + else { + $trailingcommentIDwithLineBreaks = join( "(?:\\h|\\R)*", split( //, $trailingcommentID ) ); } - my $trailingcommentIDwithLineBreaksRegExp = qr/$trailingcommentIDwithLineBreaks/s; + my $trailingcommentIDwithLineBreaksRegExp = qr/$trailingcommentIDwithLineBreaks/s; # replace the line-broken trailing comment ID with a non-broken trailing comment ID ${$self}{body} =~ s/%\R?$trailingcommentIDwithLineBreaksRegExp/%$trailingcommentID/s; - } - my $notPreceededBy = qr/${${$mainSettings{fineTuning}}{trailingComments}}{notPreceededBy}/; - if(${$self}{body} =~ m/%$trailingcommentID + } + my $notPreceededBy = qr/${${$mainSettings{fineTuning}}{trailingComments}}{notPreceededBy}/; + if (${$self}{body} =~ m/%$trailingcommentID ( (?! # not immediately preceeded by $notPreceededBy # \ @@ -128,15 +139,19 @@ sub put_trailing_comments_back_in{ ).*? ) # captured into $1 (\h*)?$ - /mx and $1 ne ''){ - $logger->trace("Comment not at end of line $trailingcommentID, moving it to end of line")if $is_t_switch_active; - ${$self}{body} =~ s/%$trailingcommentID(.*)$/$1%$trailingcommentValue/m; - #####if(${$self}{body} =~ m/%$trailingcommentID\h*[^%]+?$/mx){ - ##### $logger->trace("Comment not at end of line $trailingcommentID, moving it to end of line") if $is_t_switch_active; - } else { - ${$self}{body} =~ s/%$trailingcommentID/%$trailingcommentValue/; - } - $logger->trace("replace %$trailingcommentID with %$trailingcommentValue") if($is_tt_switch_active); + /mx and $1 ne '' + ) + { + $logger->trace("Comment not at end of line $trailingcommentID, moving it to end of line") + if $is_t_switch_active; + ${$self}{body} =~ s/%$trailingcommentID(.*)$/$1%$trailingcommentValue/m; + #####if(${$self}{body} =~ m/%$trailingcommentID\h*[^%]+?$/mx){ + ##### $logger->trace("Comment not at end of line $trailingcommentID, moving it to end of line") if $is_t_switch_active; + } + else { + ${$self}{body} =~ s/%$trailingcommentID/%$trailingcommentValue/; + } + $logger->trace("replace %$trailingcommentID with %$trailingcommentValue") if ($is_tt_switch_active); } return; } diff --git a/Master/texmf-dist/scripts/latexindent/LatexIndent/UnNamedGroupingBracesBrackets.pm b/Master/texmf-dist/scripts/latexindent/LatexIndent/UnNamedGroupingBracesBrackets.pm index 55f0d7fa27f..b1d619fad63 100644 --- a/Master/texmf-dist/scripts/latexindent/LatexIndent/UnNamedGroupingBracesBrackets.pm +++ b/Master/texmf-dist/scripts/latexindent/LatexIndent/UnNamedGroupingBracesBrackets.pm @@ -1,4 +1,5 @@ package LatexIndent::UnNamedGroupingBracesBrackets; + # 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 @@ -22,13 +23,14 @@ use LatexIndent::TrailingComments qw/$trailingCommentRegExp/; use LatexIndent::Switches qw/$is_t_switch_active $is_tt_switch_active/; use LatexIndent::LogFile qw/$logger/; use Exporter qw/import/; -our @ISA = "LatexIndent::Command"; # class inheritance, Programming Perl, pg 321 -our @EXPORT_OK = qw/construct_unnamed_grouping_braces_brackets_regexp $un_named_grouping_braces_RegExp $un_named_grouping_braces_RegExp_trailing_comment/; +our @ISA = "LatexIndent::Command"; # class inheritance, Programming Perl, pg 321 +our @EXPORT_OK + = qw/construct_unnamed_grouping_braces_brackets_regexp $un_named_grouping_braces_RegExp $un_named_grouping_braces_RegExp_trailing_comment/; our $unNamedGroupingBracesCounter; our $un_named_grouping_braces_RegExp; -our $un_named_grouping_braces_RegExp_trailing_comment; +our $un_named_grouping_braces_RegExp_trailing_comment; -sub construct_unnamed_grouping_braces_brackets_regexp{ +sub construct_unnamed_grouping_braces_brackets_regexp { my $self = shift; # grab the arguments regexp @@ -38,10 +40,10 @@ sub construct_unnamed_grouping_braces_brackets_regexp{ my $blankLineToken = $tokens{blanklines}; # arguments Before, by default, includes beamer special and numbered arguments, for example #1 #2, etc - my $argumentsBefore = qr/${${$mainSettings{fineTuning}}{arguments}}{before}/; + my $argumentsBefore = qr/${${$mainSettings{fineTuning}}{arguments}}{before}/; my $UnNamedGroupingFollowRegExp = qr/${${$mainSettings{fineTuning}}{UnNamedGroupingBracesBrackets}}{follow}/; - # store the regular expresssion for matching and replacing + # store the regular expresssion for matching and replacing $un_named_grouping_braces_RegExp = qr/ # NOT (?! @@ -64,10 +66,11 @@ sub construct_unnamed_grouping_braces_brackets_regexp{ (\R)? # $6 linebreak /sx; - $un_named_grouping_braces_RegExp_trailing_comment = qr/$un_named_grouping_braces_RegExp(\h*)((?:$trailingCommentRegExp\h*)*)?/; + $un_named_grouping_braces_RegExp_trailing_comment + = qr/$un_named_grouping_braces_RegExp(\h*)((?:$trailingCommentRegExp\h*)*)?/; } -sub create_unique_id{ +sub create_unique_id { my $self = shift; $unNamedGroupingBracesCounter++; @@ -75,31 +78,32 @@ sub create_unique_id{ return; } -sub get_replacement_text{ +sub get_replacement_text { my $self = shift; - # the replacement text for a key = {value} needes to accomodate the leading [ OR { OR % OR , OR any combination thereof + # the replacement text for a key = {value} needes to accomodate the leading [ OR { OR % OR , OR any combination thereof $logger->trace("Custom replacement text routine for ${$self}{name}") if $is_t_switch_active; - # the un-named object is a little special, as it doesn't have a name; as such, if there are blank lines before - # the braces/brackets, we have to insert them - # - # also, the argument reg-exp can pick up a leading comment (with line break), which needs to be put - # into the replacement text (see documentation/demonstrations/pstricks.tex and test-cases/unnamed-braces/unnamed.tex for example) +# the un-named object is a little special, as it doesn't have a name; as such, if there are blank lines before +# the braces/brackets, we have to insert them +# +# also, the argument reg-exp can pick up a leading comment (with line break), which needs to be put +# into the replacement text (see documentation/demonstrations/pstricks.tex and test-cases/unnamed-braces/unnamed.tex for example) ${$self}{body} =~ s/(.*?)(\{|\[)/$2/s; - ${$self}{replacementText} = ${$self}{beginningbit}.($1 ne ''?$1:q()).${$self}{id}; + ${$self}{replacementText} = ${$self}{beginningbit} . ( $1 ne '' ? $1 : q() ) . ${$self}{id}; # but now turn off the switch for linebreaksAtEnd{begin}, otherwise the first brace gets too much indentation # (see, for example, test-cases/namedGroupingBracesBrackets/special-characters-minimal.tex) - ${${$self}{linebreaksAtEnd}}{begin} = 0; - $logger->trace("Beginning bit is: ${$self}{beginningbit}") if($is_t_switch_active); + ${ ${$self}{linebreaksAtEnd} }{begin} = 0; + $logger->trace("Beginning bit is: ${$self}{beginningbit}") if ($is_t_switch_active); delete ${$self}{beginningbit}; } -sub check_for_blank_lines_at_beginning{ - # some examples can have blank line tokens at the beginning of the body, - # which can confuse the routine below - # See, for example, +sub check_for_blank_lines_at_beginning { + + # some examples can have blank line tokens at the beginning of the body, + # which can confuse the routine below + # See, for example, # test-cases/namedGroupingBracesBrackets/special-characters-minimal-blank-lines-m-switch.tex # compared to # test-cases/namedGroupingBracesBrackets/special-characters-minimal-blank-lines-default.tex @@ -109,7 +113,7 @@ sub check_for_blank_lines_at_beginning{ my $blankLineToken = $tokens{blanklines}; # if the body begins with 2 or more blank line tokens - if(${$self}{body} =~ m/^((?:$blankLineToken\R){2,})/s){ + if ( ${$self}{body} =~ m/^((?:$blankLineToken\R){2,})/s ) { # remove them ${$self}{body} =~ s/^((?:$blankLineToken\R)+)//s; @@ -118,21 +122,21 @@ sub check_for_blank_lines_at_beginning{ my $blank_line_tokens_at_beginning_of_body = $1; # and count them, for use after the indentation routine - ${$self}{blankLinesAtBeginning} = () = $blank_line_tokens_at_beginning_of_body =~ /$blankLineToken\R/sg + ${$self}{blankLinesAtBeginning} = () = $blank_line_tokens_at_beginning_of_body =~ /$blankLineToken\R/sg; } return; } -sub put_blank_lines_back_in_at_beginning{ +sub put_blank_lines_back_in_at_beginning { my $self = shift; # some bodies have blank lines at the beginning - if(${$self}{blankLinesAtBeginning}){ - for(my $i=0; $i<${$self}{blankLinesAtBeginning}; $i++){ - ${$self}{body} = $tokens{blanklines}.${$self}{body}; + if ( ${$self}{blankLinesAtBeginning} ) { + for ( my $i = 0; $i < ${$self}{blankLinesAtBeginning}; $i++ ) { + ${$self}{body} = $tokens{blanklines} . ${$self}{body}; } } - return + return; } 1; diff --git a/Master/texmf-dist/scripts/latexindent/LatexIndent/Verbatim.pm b/Master/texmf-dist/scripts/latexindent/LatexIndent/Verbatim.pm index edff0698a84..8efbeaf8774 100644 --- a/Master/texmf-dist/scripts/latexindent/LatexIndent/Verbatim.pm +++ b/Master/texmf-dist/scripts/latexindent/LatexIndent/Verbatim.pm @@ -1,4 +1,5 @@ package LatexIndent::Verbatim; + # 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 @@ -22,38 +23,46 @@ use LatexIndent::Tokens qw/%tokens/; use LatexIndent::GetYamlSettings qw/%mainSettings/; use LatexIndent::Switches qw/$is_t_switch_active $is_tt_switch_active $is_m_switch_active/; use LatexIndent::LogFile qw/$logger/; -our @EXPORT_OK = qw/put_verbatim_back_in find_verbatim_environments find_noindent_block find_verbatim_commands find_verbatim_special verbatim_common_tasks %verbatimStorage/; -our @ISA = "LatexIndent::Document"; # class inheritance, Programming Perl, pg 321 +our @EXPORT_OK + = qw/put_verbatim_back_in find_verbatim_environments find_noindent_block find_verbatim_commands find_verbatim_special verbatim_common_tasks %verbatimStorage/; +our @ISA = "LatexIndent::Document"; # class inheritance, Programming Perl, pg 321 our $verbatimCounter; our %verbatimStorage; -sub find_noindent_block{ +sub find_noindent_block { my $self = shift; # noindent block $logger->trace('*Searching for NOINDENTBLOCK (see noIndentBlock)') if $is_t_switch_active; - $logger->trace(Dumper(\%{$mainSettings{noIndentBlock}})) if($is_tt_switch_active); - while( my ($noIndentBlock,$yesno)= each %{$mainSettings{noIndentBlock}}){ + $logger->trace( Dumper( \%{ $mainSettings{noIndentBlock} } ) ) if ($is_tt_switch_active); + while ( my ( $noIndentBlock, $yesno ) = each %{ $mainSettings{noIndentBlock} } ) { # integrity check on the field for noIndentBlock - if ( ref($yesno) eq "HASH" ){ - if (defined ${$yesno}{lookForThis} and !${$yesno}{lookForThis}){ + if ( ref($yesno) eq "HASH" ) { + if ( defined ${$yesno}{lookForThis} and !${$yesno}{lookForThis} ) { $logger->trace(" *not* looking for $noIndentBlock as lookForThis: 0") if $is_t_switch_active; next; } - if (not defined ${$yesno}{name}) { - if (not defined ${$yesno}{begin}){ - $logger->trace(" *not* looking for $noIndentBlock as $noIndentBlock:begin not specified") if $is_t_switch_active; + if ( not defined ${$yesno}{name} ) { + if ( not defined ${$yesno}{begin} ) { + $logger->trace(" *not* looking for $noIndentBlock as $noIndentBlock:begin not specified") + if $is_t_switch_active; next; - } elsif (not defined ${$yesno}{end}) { - $logger->trace(" *not* looking for $noIndentBlock as $noIndentBlock:end not specified") if $is_t_switch_active; + } + elsif ( not defined ${$yesno}{end} ) { + $logger->trace(" *not* looking for $noIndentBlock as $noIndentBlock:end not specified") + if $is_t_switch_active; next; } - } elsif (defined ${$yesno}{begin} or defined ${$yesno}{end}){ - $logger->trace(" *not* looking for $noIndentBlock as $noIndentBlock:name specified with begin and/or end") if $is_t_switch_active; + } + elsif ( defined ${$yesno}{begin} or defined ${$yesno}{end} ) { + $logger->trace( + " *not* looking for $noIndentBlock as $noIndentBlock:name specified with begin and/or end") + if $is_t_switch_active; next; } - } elsif( ref($yesno) ne "HASH" and !$yesno ){ + } + elsif ( ref($yesno) ne "HASH" and !$yesno ) { $logger->trace(" *not* looking for $noIndentBlock as $noIndentBlock:$yesno") if $is_t_switch_active; next; } @@ -62,25 +71,31 @@ sub find_noindent_block{ my $noIndentRegExp; my $noIndentBlockObj; - if (ref($yesno) eq "HASH"){ + if ( ref($yesno) eq "HASH" ) { + # default value of begin and end - if (defined ${$yesno}{name} and not defined ${$yesno}{begin} and not defined ${$yesno}{end}){ + if ( defined ${$yesno}{name} and not defined ${$yesno}{begin} and not defined ${$yesno}{end} ) { ${$yesno}{begin} = "\\\\begin\\{(${$yesno}{name})\\}"; - ${$yesno}{end} = "\\\\end\\{\\2\\}"; + ${$yesno}{end} = "\\\\end\\{\\2\\}"; $logger->trace("looking for regex based $noIndentBlock, name: ${$yesno}{name}") if $is_t_switch_active; - $logger->trace("begin not specified for $noIndentBlock, setting default ${$yesno}{begin}") if $is_t_switch_active; - $logger->trace("end not specified for $noIndentBlock, setting default ${$yesno}{end}") if $is_t_switch_active; + $logger->trace("begin not specified for $noIndentBlock, setting default ${$yesno}{begin}") + if $is_t_switch_active; + $logger->trace("end not specified for $noIndentBlock, setting default ${$yesno}{end}") + if $is_t_switch_active; } + # default value of body - if (not defined ${$yesno}{body}){ - $logger->trace("looking for regex based $noIndentBlock, begin: ${$yesno}{begin}, end: ${$yesno}{end}") if $is_t_switch_active; + if ( not defined ${$yesno}{body} ) { + $logger->trace("looking for regex based $noIndentBlock, begin: ${$yesno}{begin}, end: ${$yesno}{end}") + if $is_t_switch_active; $logger->trace("body not specified for $noIndentBlock, setting default .*?") if $is_t_switch_active; ${$yesno}{body} = qr/.*?/sx; - } else { + } + else { $logger->trace("looking for regex based $noIndentBlock") if $is_t_switch_active; - $logger->trace("begin: ${$yesno}{begin}") if $is_t_switch_active; - $logger->trace("body: ${$yesno}{body}") if $is_t_switch_active; - $logger->trace("end: ${$yesno}{end}") if $is_t_switch_active; + $logger->trace("begin: ${$yesno}{begin}") if $is_t_switch_active; + $logger->trace("body: ${$yesno}{body}") if $is_t_switch_active; + $logger->trace("end: ${$yesno}{end}") if $is_t_switch_active; } $noIndentRegExp = qr/ @@ -88,10 +103,11 @@ sub find_noindent_block{ (${$yesno}{body}) (${$yesno}{end}) /sx; - } else { + } + else { $logger->trace("looking for $noIndentBlock:$yesno noIndentBlock") if $is_t_switch_active; - (my $noIndentBlockSpec = $noIndentBlock) =~ s/\*/\\*/sg; + ( my $noIndentBlockSpec = $noIndentBlock ) =~ s/\*/\\*/sg; $noIndentRegExp = qr/ ( (?!<\\) @@ -111,76 +127,86 @@ sub find_noindent_block{ \\end\{\2\} # % \end{noindentblock} statement ) # end statement captured into $4 /sx; - } - while( ${$self}{body} =~ m/$noIndentRegExp/sx){ - - # create a new Verbatim object - if (ref($yesno) eq "HASH" and not defined ${$yesno}{name}){ - # user defined begin and end statements - $noIndentBlockObj = LatexIndent::Verbatim->new( begin=>$1, - body=>$2, - end=>$3, - name=>$noIndentBlock, - type=>"noindentblock", - modifyLineBreaksYamlName=>"verbatim", - ); - } else { - # specified by name (entry:1 or entry: name: regex) - $noIndentBlockObj = LatexIndent::Verbatim->new( begin=>$1, - body=>$3, - end=>$4, - name=>$2, - type=>"noindentblock", - modifyLineBreaksYamlName=>"verbatim", - ); - } - - # give unique id - $noIndentBlockObj->create_unique_id; - - # verbatim children go in special hash - $verbatimStorage{${$noIndentBlockObj}{id}}=$noIndentBlockObj; - - # log file output - $logger->trace("NOINDENTBLOCK found: ${$noIndentBlockObj}{name}") if $is_t_switch_active; - - # remove the environment block, and replace with unique ID - ${$self}{body} =~ s/$noIndentRegExp/${$noIndentBlockObj}{id}/sx; - - $logger->trace("replaced with ID: ${$noIndentBlockObj}{id}") if $is_t_switch_active; - - # possible decoration in log file - $logger->trace(${$mainSettings{logFilePreferences}}{showDecorationFinishCodeBlockTrace}) if ${$mainSettings{logFilePreferences}}{showDecorationFinishCodeBlockTrace}; - } + } + while ( ${$self}{body} =~ m/$noIndentRegExp/sx ) { + + # create a new Verbatim object + if ( ref($yesno) eq "HASH" and not defined ${$yesno}{name} ) { + + # user defined begin and end statements + $noIndentBlockObj = LatexIndent::Verbatim->new( + begin => $1, + body => $2, + end => $3, + name => $noIndentBlock, + type => "noindentblock", + modifyLineBreaksYamlName => "verbatim", + ); + } + else { + # specified by name (entry:1 or entry: name: regex) + $noIndentBlockObj = LatexIndent::Verbatim->new( + begin => $1, + body => $3, + end => $4, + name => $2, + type => "noindentblock", + modifyLineBreaksYamlName => "verbatim", + ); + } + + # give unique id + $noIndentBlockObj->create_unique_id; + + # verbatim children go in special hash + $verbatimStorage{ ${$noIndentBlockObj}{id} } = $noIndentBlockObj; + + # log file output + $logger->trace("NOINDENTBLOCK found: ${$noIndentBlockObj}{name}") if $is_t_switch_active; + + # remove the environment block, and replace with unique ID + ${$self}{body} =~ s/$noIndentRegExp/${$noIndentBlockObj}{id}/sx; + + $logger->trace("replaced with ID: ${$noIndentBlockObj}{id}") if $is_t_switch_active; + + # possible decoration in log file + $logger->trace( ${ $mainSettings{logFilePreferences} }{showDecorationFinishCodeBlockTrace} ) + if ${ $mainSettings{logFilePreferences} }{showDecorationFinishCodeBlockTrace}; + } } return; } -sub find_verbatim_environments{ +sub find_verbatim_environments { my $self = shift; # verbatim environments $logger->trace('*Searching for VERBATIM environments (see verbatimEnvironments)') if $is_t_switch_active; - $logger->trace(Dumper(\%{$mainSettings{verbatimEnvironments}})) if($is_tt_switch_active); - while( my ($verbEnv,$yesno)= each %{$mainSettings{verbatimEnvironments}}){ + $logger->trace( Dumper( \%{ $mainSettings{verbatimEnvironments} } ) ) if ($is_tt_switch_active); + while ( my ( $verbEnv, $yesno ) = each %{ $mainSettings{verbatimEnvironments} } ) { my $verbEnvSpec; # integrity check on the field for noIndentBlock - if ( ref($yesno) eq "HASH" ){ - if (defined ${$yesno}{lookForThis} and !${$yesno}{lookForThis}){ + if ( ref($yesno) eq "HASH" ) { + if ( defined ${$yesno}{lookForThis} and !${$yesno}{lookForThis} ) { $logger->trace(" *not* looking for $verbEnv as lookForThis: 0") if $is_t_switch_active; next; - } elsif (not defined ${$yesno}{name}){ + } + elsif ( not defined ${$yesno}{name} ) { $logger->trace(" *not* looking for $verbEnv as $verbEnv:name not specified") if $is_t_switch_active; next; - } else { - $logger->trace("looking for VERBATIM-environments $verbEnv, name: ${$yesno}{name}") if $is_t_switch_active; + } + else { + $logger->trace("looking for VERBATIM-environments $verbEnv, name: ${$yesno}{name}") + if $is_t_switch_active; $verbEnvSpec = ${$yesno}{name}; } - } elsif( ref($yesno) ne "HASH" and $yesno ){ + } + elsif ( ref($yesno) ne "HASH" and $yesno ) { $logger->trace("looking for $verbEnv:$yesno environments") if $is_t_switch_active; - ($verbEnvSpec = $verbEnv) =~ s/\*/\\*/sg; - } else { + ( $verbEnvSpec = $verbEnv ) =~ s/\*/\\*/sg; + } + else { $logger->trace(" *not* looking for $verbEnv as $verbEnv:$yesno") if $is_t_switch_active; next; } @@ -202,32 +228,33 @@ sub find_verbatim_environments{ (\R)? # possibly followed by a line break /sx; - while( ${$self}{body} =~ m/$verbatimRegExp/sx){ + while ( ${$self}{body} =~ m/$verbatimRegExp/sx ) { # create a new Verbatim object - my $verbatimBlock = LatexIndent::Verbatim->new( begin=>$1, - body=>$3, - end=>$4, - name=>$2, - type=>"environment", - modifyLineBreaksYamlName=>"verbatim", - linebreaksAtEnd=>{ - end=>$6?1:0, - }, - horizontalTrailingSpace=>$5?$5:q(), - aliases=>{ - # begin statements - BeginStartsOnOwnLine=>"VerbatimBeginStartsOnOwnLine", - # after end statements - EndFinishesWithLineBreak=>"VerbatimEndFinishesWithLineBreak", - }, - ); + my $verbatimBlock = LatexIndent::Verbatim->new( + begin => $1, + body => $3, + end => $4, + name => $2, + type => "environment", + modifyLineBreaksYamlName => "verbatim", + linebreaksAtEnd => { end => $6 ? 1 : 0, }, + horizontalTrailingSpace => $5 ? $5 : q(), + aliases => { + + # begin statements + BeginStartsOnOwnLine => "VerbatimBeginStartsOnOwnLine", + + # after end statements + EndFinishesWithLineBreak => "VerbatimEndFinishesWithLineBreak", + }, + ); # there are common tasks for each of the verbatim objects $verbatimBlock->verbatim_common_tasks; - + # verbatim children go in special hash - $verbatimStorage{${$verbatimBlock}{id}}=$verbatimBlock; + $verbatimStorage{ ${$verbatimBlock}{id} } = $verbatimBlock; # log file output $logger->trace("*VERBATIM environment found: ${$verbatimBlock}{name}") if $is_t_switch_active; @@ -236,43 +263,50 @@ sub find_verbatim_environments{ ${$self}{body} =~ s/$verbatimRegExp/${$verbatimBlock}{replacementText}/sx; $logger->trace("replaced with ID: ${$verbatimBlock}{id}") if $is_t_switch_active; - + # possible decoration in log file - $logger->trace(${$mainSettings{logFilePreferences}}{showDecorationFinishCodeBlockTrace}) if ${$mainSettings{logFilePreferences}}{showDecorationFinishCodeBlockTrace}; - } + $logger->trace( ${ $mainSettings{logFilePreferences} }{showDecorationFinishCodeBlockTrace} ) + if ${ $mainSettings{logFilePreferences} }{showDecorationFinishCodeBlockTrace}; + } } return; } -sub find_verbatim_commands{ +sub find_verbatim_commands { my $self = shift; # verbatim commands need to be treated separately to verbatim environments; - # note that, for example, we could quite reasonably have \lstinline!%!, which - # would need to be found *before* trailing comments have been removed. Similarly, - # verbatim commands need to be put back in *after* trailing comments have been put + # note that, for example, we could quite reasonably have \lstinline!%!, which + # would need to be found *before* trailing comments have been removed. Similarly, + # verbatim commands need to be put back in *after* trailing comments have been put # back in $logger->trace('*Searching for VERBATIM commands (see verbatimCommands)') if $is_t_switch_active; - $logger->trace(Dumper(\%{$mainSettings{verbatimCommands}})) if($is_tt_switch_active); - while( my ($verbCommand,$yesno)= each %{$mainSettings{verbatimCommands}}){ + $logger->trace( Dumper( \%{ $mainSettings{verbatimCommands} } ) ) if ($is_tt_switch_active); + while ( my ( $verbCommand, $yesno ) = each %{ $mainSettings{verbatimCommands} } ) { my $verbCommandSpec; # integrity check on the field for noIndentBlock - if ( ref($yesno) eq "HASH" ){ - if (defined ${$yesno}{lookForThis} and !${$yesno}{lookForThis}){ + if ( ref($yesno) eq "HASH" ) { + if ( defined ${$yesno}{lookForThis} and !${$yesno}{lookForThis} ) { $logger->trace(" *not* looking for $verbCommand as lookForThis: 0") if $is_t_switch_active; next; - } elsif (not defined ${$yesno}{name}){ - $logger->trace(" *not* looking for $verbCommand as $verbCommand:name not specified") if $is_t_switch_active; + } + elsif ( not defined ${$yesno}{name} ) { + $logger->trace(" *not* looking for $verbCommand as $verbCommand:name not specified") + if $is_t_switch_active; next; - } else { - $logger->trace("looking for regex based VERBATIM-commands $verbCommand, name: ${$yesno}{name}") if $is_t_switch_active; + } + else { + $logger->trace("looking for regex based VERBATIM-commands $verbCommand, name: ${$yesno}{name}") + if $is_t_switch_active; $verbCommandSpec = ${$yesno}{name}; } - } elsif( ref($yesno) ne "HASH" and $yesno ){ + } + elsif ( ref($yesno) ne "HASH" and $yesno ) { $logger->trace("looking for $verbCommand:$yesno Commands") if $is_t_switch_active; $verbCommandSpec = $verbCommand; - } else { + } + else { $logger->trace("*not* looking for $verbCommand as $verbCommand:$yesno") if $is_t_switch_active; next; } @@ -305,42 +339,48 @@ sub find_verbatim_commands{ (\R)? # possibly followed by a line break /mx; - while( ${$self}{body} =~ m/$verbatimRegExp/){ + while ( ${$self}{body} =~ m/$verbatimRegExp/ ) { # create a new Verbatim object - my $verbatimCommand = LatexIndent::Verbatim->new( begin=>$1.($3?$3:q()).$4, - body=>$5, - end=>$4, - name=>$2, - type=>"command", - modifyLineBreaksYamlName=>"verbatim", - linebreaksAtEnd=>{ - end=>$7?1:0, - }, - horizontalTrailingSpace=>$6?$6:q(), - aliases=>{ - # begin statements - BeginStartsOnOwnLine=>"VerbatimBeginStartsOnOwnLine", - # after end statements - EndFinishesWithLineBreak=>"VerbatimEndFinishesWithLineBreak", - }, - optArg=>$3?$3:q(), - ); + my $verbatimCommand = LatexIndent::Verbatim->new( + begin => $1 . ( $3 ? $3 : q() ) . $4, + body => $5, + end => $4, + name => $2, + type => "command", + modifyLineBreaksYamlName => "verbatim", + linebreaksAtEnd => { end => $7 ? 1 : 0, }, + horizontalTrailingSpace => $6 ? $6 : q(), + aliases => { + + # begin statements + BeginStartsOnOwnLine => "VerbatimBeginStartsOnOwnLine", + + # after end statements + EndFinishesWithLineBreak => "VerbatimEndFinishesWithLineBreak", + }, + optArg => $3 ? $3 : q(), + ); + # there are common tasks for each of the verbatim objects $verbatimCommand->verbatim_common_tasks; # output, if desired - $logger->trace(Dumper($verbatimCommand),'ttrace') if($is_tt_switch_active); + $logger->trace( Dumper($verbatimCommand), 'ttrace' ) if ($is_tt_switch_active); # check for nested verbatim commands - if(${$verbatimCommand}{body} =~ m/($tokens{verbatimInline}\d+$tokens{endOfToken})/s){ + if ( ${$verbatimCommand}{body} =~ m/($tokens{verbatimInline}\d+$tokens{endOfToken})/s ) { my $verbatimNestedID = $1; - my $verbatimBody = ${$verbatimStorage{$verbatimNestedID}}{begin}.${$verbatimStorage{$verbatimNestedID}}{body}.${$verbatimStorage{$verbatimNestedID}}{end}; + my $verbatimBody + = ${ $verbatimStorage{$verbatimNestedID} }{begin} + . ${ $verbatimStorage{$verbatimNestedID} }{body} + . ${ $verbatimStorage{$verbatimNestedID} }{end}; ${$verbatimCommand}{body} =~ s/$verbatimNestedID/$verbatimBody/s; delete $verbatimStorage{$verbatimNestedID}; } + # verbatim children go in special hash - $verbatimStorage{${$verbatimCommand}{id}}=$verbatimCommand; + $verbatimStorage{ ${$verbatimCommand}{id} } = $verbatimCommand; # log file output $logger->trace("*VERBATIM command found: ${$verbatimCommand}{name}") if $is_t_switch_active; @@ -349,23 +389,27 @@ sub find_verbatim_commands{ ${$self}{body} =~ s/$verbatimRegExp/${$verbatimCommand}{replacementText}/sx; $logger->trace("replaced with ID: ${$verbatimCommand}{id}") if $is_t_switch_active; - - # possible decoration in log file - $logger->trace(${$mainSettings{logFilePreferences}}{showDecorationFinishCodeBlockTrace}) if ${$mainSettings{logFilePreferences}}{showDecorationFinishCodeBlockTrace}; + + # possible decoration in log file + $logger->trace( ${ $mainSettings{logFilePreferences} }{showDecorationFinishCodeBlockTrace} ) + if ${ $mainSettings{logFilePreferences} }{showDecorationFinishCodeBlockTrace}; } } return; } -sub find_verbatim_special{ +sub find_verbatim_special { my $self = shift; # loop through specialBeginEnd - while( my ($specialName,$BeginEnd)= each %{$mainSettings{specialBeginEnd}}){ + while ( my ( $specialName, $BeginEnd ) = each %{ $mainSettings{specialBeginEnd} } ) { - # only classify special Verbatim if lookForThis is 'verbatim' - if( (ref($BeginEnd) eq "HASH") and ${$BeginEnd}{lookForThis}=~m/v/s and ${$BeginEnd}{lookForThis} eq 'verbatim'){ + # only classify special Verbatim if lookForThis is 'verbatim' + if ( ( ref($BeginEnd) eq "HASH" ) + and ${$BeginEnd}{lookForThis} =~ m/v/s + and ${$BeginEnd}{lookForThis} eq 'verbatim' ) + { $logger->trace('*Searching for VERBATIM special (see specialBeginEnd)') if $is_t_switch_active; my $verbatimRegExp = qr/ @@ -382,140 +426,152 @@ sub find_verbatim_special{ (\R)? # possibly followed by a line break /sx; - while( ${$self}{body} =~ m/$verbatimRegExp/sx){ - - # create a new Verbatim object - my $verbatimBlock = LatexIndent::Verbatim->new( begin=>$1, - body=>$2, - end=>$3, - name=>$specialName, - modifyLineBreaksYamlName=>"specialBeginEnd", - linebreaksAtEnd=>{ - end=>$5?1:0, - }, - horizontalTrailingSpace=>$4?$4:q(), - type=>"special", - aliases=>{ - # begin statements - BeginStartsOnOwnLine=>"SpecialBeginStartsOnOwnLine", - # after end statements - EndFinishesWithLineBreak=>"SpecialEndFinishesWithLineBreak", - }, - ); - # there are common tasks for each of the verbatim objects - $verbatimBlock->verbatim_common_tasks; - - # verbatim children go in special hash - $verbatimStorage{${$verbatimBlock}{id}}=$verbatimBlock; - - # log file output - $logger->trace("*VERBATIM special found: $specialName") if $is_t_switch_active; - - # remove the special block, and replace with unique ID - ${$self}{body} =~ s/$verbatimRegExp/${$verbatimBlock}{replacementText}/sx; - - $logger->trace("replaced with ID: ${$verbatimBlock}{id}") if $is_t_switch_active; - - # possible decoration in log file - $logger->trace(${$mainSettings{logFilePreferences}}{showDecorationFinishCodeBlockTrace}) if ${$mainSettings{logFilePreferences}}{showDecorationFinishCodeBlockTrace}; - } + while ( ${$self}{body} =~ m/$verbatimRegExp/sx ) { + + # create a new Verbatim object + my $verbatimBlock = LatexIndent::Verbatim->new( + begin => $1, + body => $2, + end => $3, + name => $specialName, + modifyLineBreaksYamlName => "specialBeginEnd", + linebreaksAtEnd => { end => $5 ? 1 : 0, }, + horizontalTrailingSpace => $4 ? $4 : q(), + type => "special", + aliases => { + + # begin statements + BeginStartsOnOwnLine => "SpecialBeginStartsOnOwnLine", + + # after end statements + EndFinishesWithLineBreak => "SpecialEndFinishesWithLineBreak", + }, + ); + + # there are common tasks for each of the verbatim objects + $verbatimBlock->verbatim_common_tasks; + + # verbatim children go in special hash + $verbatimStorage{ ${$verbatimBlock}{id} } = $verbatimBlock; + + # log file output + $logger->trace("*VERBATIM special found: $specialName") if $is_t_switch_active; + + # remove the special block, and replace with unique ID + ${$self}{body} =~ s/$verbatimRegExp/${$verbatimBlock}{replacementText}/sx; + + $logger->trace("replaced with ID: ${$verbatimBlock}{id}") if $is_t_switch_active; + + # possible decoration in log file + $logger->trace( ${ $mainSettings{logFilePreferences} }{showDecorationFinishCodeBlockTrace} ) + if ${ $mainSettings{logFilePreferences} }{showDecorationFinishCodeBlockTrace}; + } + } } - } } -sub put_verbatim_back_in { - my $self = shift; +sub put_verbatim_back_in { + my $self = shift; my %input = @_; - my $verbatimCount=0; - my $toMatch = q(); - if($input{match} eq "everything-except-commands"){ + my $verbatimCount = 0; + my $toMatch = q(); + if ( $input{match} eq "everything-except-commands" ) { $toMatch = "noindentblockenvironmentspeciallinesprotect"; - } else { + } + else { $toMatch = "command"; } # count the number of non-command verbatim objects - while( my ($key,$child)= each %verbatimStorage){ - ${$child}{type} = "environment" if !(defined ${$child}{type}); - $verbatimCount++ if($toMatch =~ m/${$child}{type}/); + while ( my ( $key, $child ) = each %verbatimStorage ) { + ${$child}{type} = "environment" if !( defined ${$child}{type} ); + $verbatimCount++ if ( $toMatch =~ m/${$child}{type}/ ); } - return unless($verbatimCount>0); - + return unless ( $verbatimCount > 0 ); + # search for environments/commands $logger->trace('*Putting verbatim back in') if $is_t_switch_active; - $logger->trace('pre-processed body:') if $is_tt_switch_active; - $logger->trace(${$self}{body}) if($is_tt_switch_active); + $logger->trace('pre-processed body:') if $is_tt_switch_active; + $logger->trace( ${$self}{body} ) if ($is_tt_switch_active); # loop through document children hash - my $verbatimFound=0; - while($verbatimFound < $verbatimCount){ - while( my ($verbatimID,$child)= each %verbatimStorage){ - if($toMatch =~ m/${$child}{type}/){ - if(${$self}{body} =~ m/$verbatimID/m){ - # possibly remove trailing line break - if($is_m_switch_active - and defined ${$child}{EndFinishesWithLineBreak} - and ${$child}{EndFinishesWithLineBreak}==-1 - and ${$self}{body} =~ m/$verbatimID\h*\R/s){ - $logger->trace("m-switch active, removing trailing line breaks from ${$child}{name}") if $is_t_switch_active; - ${$self}{body} =~ s/$verbatimID(\h*)?(\R|\h)*/$verbatimID /s; - } - - # line protection mode can allow line breaks to be removed - # at end of verbatim; these need to be added back in - # - # see - # - # test-cases/line-switch-test-cases/environments-simple-nested-mod13.tex - # - if(${$child}{type} eq "linesprotect"){ - # remove leading space ahead of verbatim ID - ${$self}{body} =~ s/^\h*$verbatimID/$verbatimID/m; - - if($is_m_switch_active and ${$self}{body}=~ m/$verbatimID\h*\S/s){ - ${$self}{body} =~ s/$verbatimID\h*(\S)/$verbatimID\n$1/s; + my $verbatimFound = 0; + while ( $verbatimFound < $verbatimCount ) { + while ( my ( $verbatimID, $child ) = each %verbatimStorage ) { + if ( $toMatch =~ m/${$child}{type}/ ) { + if ( ${$self}{body} =~ m/$verbatimID/m ) { + + # possibly remove trailing line break + if ( $is_m_switch_active + and defined ${$child}{EndFinishesWithLineBreak} + and ${$child}{EndFinishesWithLineBreak} == -1 + and ${$self}{body} =~ m/$verbatimID\h*\R/s ) + { + $logger->trace("m-switch active, removing trailing line breaks from ${$child}{name}") + if $is_t_switch_active; + ${$self}{body} =~ s/$verbatimID(\h*)?(\R|\h)*/$verbatimID /s; } - } - # replace ids with body - ${$self}{body} =~ s/$verbatimID/${$child}{begin}${$child}{body}${$child}{end}/s; - - # log file info - $logger->trace('Body now looks like:') if $is_tt_switch_active; - $logger->trace(${$self}{body},'ttrace') if($is_tt_switch_active); - - # delete the child so it won't be operated upon again - delete $verbatimStorage{$verbatimID}; - $verbatimFound++; - } elsif ($is_m_switch_active - and ${$mainSettings{modifyLineBreaks}{textWrapOptions}}{columns}>1 - and ${$mainSettings{modifyLineBreaks}{textWrapOptions}}{huge} ne "overflow" - and ${$self}{body} !~ m/${$child}{id}/){ - $logger->trace("$verbatimID not found in body using /m matching, it may have been split across line (see modifyLineBreaks: textWrapOptions)") if($is_t_switch_active); + # line protection mode can allow line breaks to be removed + # at end of verbatim; these need to be added back in + # + # see + # + # test-cases/line-switch-test-cases/environments-simple-nested-mod13.tex + # + if ( ${$child}{type} eq "linesprotect" ) { + + # remove leading space ahead of verbatim ID + ${$self}{body} =~ s/^\h*$verbatimID/$verbatimID/m; + + if ( $is_m_switch_active and ${$self}{body} =~ m/$verbatimID\h*\S/s ) { + ${$self}{body} =~ s/$verbatimID\h*(\S)/$verbatimID\n$1/s; + } + } - # search for a version of the verbatim ID that may have line breaks - my $verbatimIDwithLineBreaks = join("\\R?",split(//,$verbatimID)); - my $verbatimIDwithLineBreaksRegExp = qr/$verbatimIDwithLineBreaks/s; + # replace ids with body + ${$self}{body} =~ s/$verbatimID/${$child}{begin}${$child}{body}${$child}{end}/s; - # replace the line-broken verbatim ID with a non-broken verbatim ID - ${$self}{body} =~ s/$verbatimIDwithLineBreaksRegExp/${$child}{id}/s; + # log file info + $logger->trace('Body now looks like:') if $is_tt_switch_active; + $logger->trace( ${$self}{body}, 'ttrace' ) if ($is_tt_switch_active); - # note: we do *not* label this as found, as we need to go back through - # and search for the newly modified ID - } + # delete the child so it won't be operated upon again + delete $verbatimStorage{$verbatimID}; + $verbatimFound++; + } + elsif ( $is_m_switch_active + and ${ $mainSettings{modifyLineBreaks}{textWrapOptions} }{columns} > 1 + and ${ $mainSettings{modifyLineBreaks}{textWrapOptions} }{huge} ne "overflow" + and ${$self}{body} !~ m/${$child}{id}/ ) + { + $logger->trace( + "$verbatimID not found in body using /m matching, it may have been split across line (see modifyLineBreaks: textWrapOptions)" + ) if ($is_t_switch_active); + + # search for a version of the verbatim ID that may have line breaks + my $verbatimIDwithLineBreaks = join( "\\R?", split( //, $verbatimID ) ); + my $verbatimIDwithLineBreaksRegExp = qr/$verbatimIDwithLineBreaks/s; + + # replace the line-broken verbatim ID with a non-broken verbatim ID + ${$self}{body} =~ s/$verbatimIDwithLineBreaksRegExp/${$child}{id}/s; + + # note: we do *not* label this as found, as we need to go back through + # and search for the newly modified ID + } } # logfile info $logger->trace('*Post-processed body:') if $is_tt_switch_active; - $logger->trace(${$self}{body}) if($is_tt_switch_active); - } + $logger->trace( ${$self}{body} ) if ($is_tt_switch_active); + } } return; } -sub verbatim_common_tasks{ +sub verbatim_common_tasks { my $self = shift; @@ -531,23 +587,31 @@ sub verbatim_common_tasks{ # the above regexp, when used below, will remove the trailing linebreak in ${$self}{linebreaksAtEnd}{end} # so we compensate for it here $self->adjust_replacement_text_line_breaks_at_end; - + # modify line breaks end statements - $self->modify_line_breaks_end if ($is_m_switch_active and defined ${$self}{EndStartsOnOwnLine} and ${$self}{EndStartsOnOwnLine}!=0); - $self->modify_line_breaks_end_after if ($is_m_switch_active and defined ${$self}{EndFinishesWithLineBreak} and ${$self}{EndFinishesWithLineBreak}!=0); + $self->modify_line_breaks_end + if ( $is_m_switch_active and defined ${$self}{EndStartsOnOwnLine} and ${$self}{EndStartsOnOwnLine} != 0 ); + $self->modify_line_breaks_end_after + if ($is_m_switch_active + and defined ${$self}{EndFinishesWithLineBreak} + and ${$self}{EndFinishesWithLineBreak} != 0 ); } -sub create_unique_id{ +sub create_unique_id { my $self = shift; $verbatimCounter++; - ${$self}{id} = (${$self}{type} eq 'command' ? $tokens{verbatimInline} : $tokens{verbatim}).$verbatimCounter.$tokens{endOfToken}; + ${$self}{id} + = ( ${$self}{type} eq 'command' ? $tokens{verbatimInline} : $tokens{verbatim} ) + . $verbatimCounter + . $tokens{endOfToken}; return; } -sub yaml_get_textwrap_removeparagraphline_breaks{ +sub yaml_get_textwrap_removeparagraphline_breaks { my $self = shift; - $logger->trace("No text wrap or remove paragraph line breaks for verbatim code blocks, ${$self}{name}") if ${$mainSettings{logFilePreferences}}{showDecorationFinishCodeBlockTrace}; + $logger->trace("No text wrap or remove paragraph line breaks for verbatim code blocks, ${$self}{name}") + if ${ $mainSettings{logFilePreferences} }{showDecorationFinishCodeBlockTrace}; } 1; diff --git a/Master/texmf-dist/scripts/latexindent/LatexIndent/Version.pm b/Master/texmf-dist/scripts/latexindent/LatexIndent/Version.pm index 4d47cc64e17..edbb6252aa5 100644 --- a/Master/texmf-dist/scripts/latexindent/LatexIndent/Version.pm +++ b/Master/texmf-dist/scripts/latexindent/LatexIndent/Version.pm @@ -1,4 +1,5 @@ package LatexIndent::Version; + # 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 @@ -19,6 +20,6 @@ use warnings; use Exporter qw/import/; our @EXPORT_OK = qw/$versionNumber $versionDate/; -our $versionNumber = '3.17.1'; -our $versionDate = '2022-04-04'; +our $versionNumber = '3.17.2'; +our $versionDate = '2022-04-14'; 1 diff --git a/Master/texmf-dist/scripts/latexindent/LatexIndent/Wrap.pm b/Master/texmf-dist/scripts/latexindent/LatexIndent/Wrap.pm index e315d0559db..1850a83c90d 100644 --- a/Master/texmf-dist/scripts/latexindent/LatexIndent/Wrap.pm +++ b/Master/texmf-dist/scripts/latexindent/LatexIndent/Wrap.pm @@ -1,4 +1,5 @@ package LatexIndent::Wrap; + # 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 @@ -25,11 +26,11 @@ use LatexIndent::Switches qw/$is_t_switch_active $is_tt_switch_active $is_m_swit use LatexIndent::LogFile qw/$logger/; use LatexIndent::Verbatim qw/%verbatimStorage/; use Exporter qw/import/; -our @ISA = "LatexIndent::Document"; # class inheritance, Programming Perl, pg 321 +our @ISA = "LatexIndent::Document"; # class inheritance, Programming Perl, pg 321 our @EXPORT_OK = qw/text_wrap/; our $sentenceCounter; -sub text_wrap{ +sub text_wrap { my $self = shift; $logger->trace("*Text wrap regular expression construction: (see textWrapOptions: )") if $is_t_switch_active; @@ -37,15 +38,16 @@ sub text_wrap{ # textWrap Blocks FOLLOW # textWrap Blocks FOLLOW # textWrap Blocks FOLLOW - my $blocksFollow = q(); - my $blocksFollowHash = \%{${$mainSettings{modifyLineBreaks}{textWrapOptions}}{blocksFollow}}; + my $blocksFollow = q(); + my $blocksFollowHash = \%{ ${ $mainSettings{modifyLineBreaks}{textWrapOptions} }{blocksFollow} }; - foreach my $blocksFollowEachPart (sort keys %{$blocksFollowHash}) { + foreach my $blocksFollowEachPart ( sort keys %{$blocksFollowHash} ) { my $yesNo = $blocksFollowHash->{$blocksFollowEachPart}; - if($yesNo){ - if($blocksFollowEachPart eq "par"){ + if ($yesNo) { + if ( $blocksFollowEachPart eq "par" ) { $blocksFollowEachPart = qr/\R?\\par/s; - } elsif ($blocksFollowEachPart eq "blankLine"){ + } + elsif ( $blocksFollowEachPart eq "blankLine" ) { $blocksFollowEachPart = qr/ (?:\A(?:$tokens{blanklines}\R)+) # the order of each of these | # is important, as (like always) the first @@ -57,84 +59,99 @@ sub text_wrap{ | \G /sx; - } elsif ($blocksFollowEachPart eq "commentOnPreviousLine"){ + } + elsif ( $blocksFollowEachPart eq "commentOnPreviousLine" ) { $blocksFollowEachPart = qr/^$trailingCommentRegExp/m; - } elsif ($blocksFollowEachPart eq "verbatim"){ + } + elsif ( $blocksFollowEachPart eq "verbatim" ) { $blocksFollowEachPart = qr/$tokens{verbatim}\d+$tokens{endOfToken}/; - } elsif ($blocksFollowEachPart eq "filecontents"){ + } + elsif ( $blocksFollowEachPart eq "filecontents" ) { $blocksFollowEachPart = qr/$tokens{filecontents}\d+$tokens{endOfToken}/; - } elsif ($blocksFollowEachPart eq "headings"){ + } + elsif ( $blocksFollowEachPart eq "headings" ) { $blocksFollowEachPart = q(); - my %headingsLevels = %{$mainSettings{indentAfterHeadings}}; - while( my ($headingName,$headingInfo)= each %headingsLevels){ - # check for a * in the name - $headingName =~ s/\*/\\\*/g; - - # make the regex as - # - # headingName - # <hspace> # possible horizontal space - # []? # possible optional argument - # <hspace> # possible horizontal space - # {} # mandatory argument - # - $headingName = qr/\\$headingName\h*(?:\[[^]]*?\])?\h*\{[^}]*?\}\h*(?:\\label\{[^}]*?\})?/m; - - # put starred headings at the front of the regexp - if($headingName =~ m/\*/){ - $blocksFollowEachPart = $headingName.($blocksFollowEachPart eq '' ?q():"|$blocksFollowEachPart"); - } else { - $blocksFollowEachPart .= ($blocksFollowEachPart eq '' ?q():"|").$headingName ; - } + my %headingsLevels = %{ $mainSettings{indentAfterHeadings} }; + while ( my ( $headingName, $headingInfo ) = each %headingsLevels ) { + + # check for a * in the name + $headingName =~ s/\*/\\\*/g; + + # make the regex as + # + # headingName + # <hspace> # possible horizontal space + # []? # possible optional argument + # <hspace> # possible horizontal space + # {} # mandatory argument + # + $headingName = qr/\\$headingName\h*(?:\[[^]]*?\])?\h*\{[^}]*?\}\h*(?:\\label\{[^}]*?\})?/m; + + # put starred headings at the front of the regexp + if ( $headingName =~ m/\*/ ) { + $blocksFollowEachPart + = $headingName . ( $blocksFollowEachPart eq '' ? q() : "|$blocksFollowEachPart" ); + } + else { + $blocksFollowEachPart .= ( $blocksFollowEachPart eq '' ? q() : "|" ) . $headingName; + } } - } elsif ($blocksFollowEachPart eq "other"){ + } + elsif ( $blocksFollowEachPart eq "other" ) { $blocksFollowEachPart = qr/$yesNo/x; } - $blocksFollow .= ($blocksFollow eq '' ? q() : "|").qr/$blocksFollowEachPart/sx; + $blocksFollow .= ( $blocksFollow eq '' ? q() : "|" ) . qr/$blocksFollowEachPart/sx; } } - # if blankLine is not active from blocksFollow then we need to set up the - # beginning of the string, but make sure that it is *not* followed by a + # if blankLine is not active from blocksFollow then we need to set up the + # beginning of the string, but make sure that it is *not* followed by a # blank line token, or a blank line - if(!${${$mainSettings{modifyLineBreaks}{textWrapOptions}}{blocksFollow}}{blankLine}){ - $blocksFollow .= ($blocksFollow eq '' ? q() : "|"). - qr/ + if ( !${ ${ $mainSettings{modifyLineBreaks}{textWrapOptions} }{blocksFollow} }{blankLine} ) { + $blocksFollow .= ( $blocksFollow eq '' ? q() : "|" ) . qr/ \G (?!$tokens{blanklines}) /sx; } # followed by 0 or more h-space and line breaks - $blocksFollow = ($blocksFollow eq '' ? q() : qr/(?:$blocksFollow)(?:\h|\R)*/sx ); + $blocksFollow = ( $blocksFollow eq '' ? q() : qr/(?:$blocksFollow)(?:\h|\R)*/sx ); $logger->trace("textWrap blocks follow regexp:") if $is_tt_switch_active; $logger->trace($blocksFollow) if $is_tt_switch_active; - + # textWrap Blocks BEGIN with # textWrap Blocks BEGIN with # textWrap Blocks BEGIN with - my $blocksBeginWith = q(); - my $blocksBeginWithHash = \%{${$mainSettings{modifyLineBreaks}{textWrapOptions}}{blocksBeginWith}}; + my $blocksBeginWith = q(); + my $blocksBeginWithHash = \%{ ${ $mainSettings{modifyLineBreaks}{textWrapOptions} }{blocksBeginWith} }; - foreach my $blocksBeginWithEachPart (sort keys %{$blocksBeginWithHash}) { + foreach my $blocksBeginWithEachPart ( sort keys %{$blocksBeginWithHash} ) { my $yesNo = $blocksBeginWithHash->{$blocksBeginWithEachPart}; - if($yesNo){ - if($blocksBeginWithEachPart eq "A-Z"){ - $logger->trace("textWrap Blocks BEGINS with capital letters (see textWrap:blocksBeginWith:A-Z)") if $is_t_switch_active; + if ($yesNo) { + if ( $blocksBeginWithEachPart eq "A-Z" ) { + $logger->trace("textWrap Blocks BEGINS with capital letters (see textWrap:blocksBeginWith:A-Z)") + if $is_t_switch_active; $blocksBeginWithEachPart = qr/(?!(?:$tokens{blanklines}|$tokens{verbatim}|$tokens{preamble}))[A-Z]/; - } elsif ($blocksBeginWithEachPart eq "a-z"){ - $logger->trace("textWrap Blocks BEGINS with lower-case letters (see textWrap:blocksBeginWith:a-z)") if $is_t_switch_active; + } + elsif ( $blocksBeginWithEachPart eq "a-z" ) { + $logger->trace("textWrap Blocks BEGINS with lower-case letters (see textWrap:blocksBeginWith:a-z)") + if $is_t_switch_active; $blocksBeginWithEachPart = qr/[a-z]/; - } elsif ($blocksBeginWithEachPart eq "0-9"){ - $logger->trace("textWrap Blocks BEGINS with numbers (see textWrap:blocksBeginWith:0-9)") if $is_t_switch_active; + } + elsif ( $blocksBeginWithEachPart eq "0-9" ) { + $logger->trace("textWrap Blocks BEGINS with numbers (see textWrap:blocksBeginWith:0-9)") + if $is_t_switch_active; $blocksBeginWithEachPart = qr/[0-9]/; - } elsif ($blocksBeginWithEachPart eq "other"){ - $logger->trace("textWrap Blocks BEGINS with other $yesNo (reg exp) (see textWrap:blocksBeginWith:other)") if $is_t_switch_active; + } + elsif ( $blocksBeginWithEachPart eq "other" ) { + $logger->trace( + "textWrap Blocks BEGINS with other $yesNo (reg exp) (see textWrap:blocksBeginWith:other)") + if $is_t_switch_active; $blocksBeginWithEachPart = qr/$yesNo/; } - $blocksBeginWith .= ($blocksBeginWith eq "" ? q(): "|" ).$blocksBeginWithEachPart; + $blocksBeginWith .= ( $blocksBeginWith eq "" ? q() : "|" ) . $blocksBeginWithEachPart; } } $blocksBeginWith = qr/$blocksBeginWith/; @@ -142,26 +159,34 @@ sub text_wrap{ # textWrap Blocks END with # textWrap Blocks END with # textWrap Blocks END with - my $blocksEndBefore = q(); - my $blocksEndBeforeHash = \%{${$mainSettings{modifyLineBreaks}{textWrapOptions}}{blocksEndBefore}}; + my $blocksEndBefore = q(); + my $blocksEndBeforeHash = \%{ ${ $mainSettings{modifyLineBreaks}{textWrapOptions} }{blocksEndBefore} }; - foreach my $blocksEndBeforeEachPart (sort keys %{$blocksEndBeforeHash}) { + foreach my $blocksEndBeforeEachPart ( sort keys %{$blocksEndBeforeHash} ) { my $yesNo = $blocksEndBeforeHash->{$blocksEndBeforeEachPart}; - if($yesNo){ - if ($blocksEndBeforeEachPart eq "other"){ - $logger->trace("textWrap Blocks ENDS with other $yesNo (reg exp) (see textWrap:blocksEndBefore:other)") if $is_t_switch_active; + if ($yesNo) { + if ( $blocksEndBeforeEachPart eq "other" ) { + $logger->trace("textWrap Blocks ENDS with other $yesNo (reg exp) (see textWrap:blocksEndBefore:other)") + if $is_t_switch_active; $blocksEndBeforeEachPart = qr/\R?$yesNo/; - } elsif ($blocksEndBeforeEachPart eq "commentOnOwnLine"){ - $logger->trace("textWrap Blocks ENDS with commentOnOwnLine (see textWrap:blocksEndBefore:commentOnOwnLine)") if $is_t_switch_active; + } + elsif ( $blocksEndBeforeEachPart eq "commentOnOwnLine" ) { + $logger->trace( + "textWrap Blocks ENDS with commentOnOwnLine (see textWrap:blocksEndBefore:commentOnOwnLine)") + if $is_t_switch_active; $blocksEndBeforeEachPart = qr/^$trailingCommentRegExp/m; - } elsif ($blocksEndBeforeEachPart eq "verbatim"){ - $logger->trace("textWrap Blocks ENDS with verbatim (see textWrap:blocksEndBefore:verbatim)") if $is_t_switch_active; + } + elsif ( $blocksEndBeforeEachPart eq "verbatim" ) { + $logger->trace("textWrap Blocks ENDS with verbatim (see textWrap:blocksEndBefore:verbatim)") + if $is_t_switch_active; $blocksEndBeforeEachPart = qr/$tokens{verbatim}\d/; - } elsif ($blocksEndBeforeEachPart eq "filecontents"){ - $logger->trace("textWrap Blocks ENDS with filecontents (see textWrap:blocksEndBefore:filecontents)") if $is_t_switch_active; + } + elsif ( $blocksEndBeforeEachPart eq "filecontents" ) { + $logger->trace("textWrap Blocks ENDS with filecontents (see textWrap:blocksEndBefore:filecontents)") + if $is_t_switch_active; $blocksEndBeforeEachPart = qr/$tokens{filecontents}/; } - $blocksEndBefore .= ($blocksEndBefore eq "" ? q(): "|" ).$blocksEndBeforeEachPart; + $blocksEndBefore .= ( $blocksEndBefore eq "" ? q() : "|" ) . $blocksEndBeforeEachPart; } } $blocksEndBefore = qr/$blocksEndBefore/; @@ -173,152 +198,163 @@ sub text_wrap{ $logger->trace($blocksEndBefore) if $is_tt_switch_active; # store the text wrap blocks - my @textWrapBlockStorage = split(/($blocksFollow)/,${$self}{body}); + my @textWrapBlockStorage = split( /($blocksFollow)/, ${$self}{body} ); # sentences need special treatment - if (${$self}{modifyLineBreaksYamlName} eq 'sentence'){ - @textWrapBlockStorage = (${$self}{body}); + if ( ${$self}{modifyLineBreaksYamlName} eq 'sentence' ) { + @textWrapBlockStorage = ( ${$self}{body} ); } # call the text wrapping routine - my $columns = ${$mainSettings{modifyLineBreaks}{textWrapOptions}}{columns}; + my $columns = ${ $mainSettings{modifyLineBreaks}{textWrapOptions} }{columns}; # vital Text::Wrap options - $Text::Wrap::columns=$columns; - $Text::Wrap::huge = ${$mainSettings{modifyLineBreaks}{textWrapOptions}}{huge}; + $Text::Wrap::columns = $columns; + $Text::Wrap::huge = ${ $mainSettings{modifyLineBreaks}{textWrapOptions} }{huge}; # all other Text::Wrap options not usually needed/helpful, but available - $Text::Wrap::separator = ${$mainSettings{modifyLineBreaks}{textWrapOptions}}{separator} if(${$mainSettings{modifyLineBreaks}{textWrapOptions}}{separator} ne ''); - $Text::Wrap::break = ${$mainSettings{modifyLineBreaks}{textWrapOptions}}{break} if ${$mainSettings{modifyLineBreaks}{textWrapOptions}}{break}; - $Text::Wrap::unexpand = ${$mainSettings{modifyLineBreaks}{textWrapOptions}}{unexpand} if ${$mainSettings{modifyLineBreaks}{textWrapOptions}}{unexpand}; - $Text::Wrap::tabstop = ${$mainSettings{modifyLineBreaks}{textWrapOptions}}{tabstop} if ${$mainSettings{modifyLineBreaks}{textWrapOptions}}{tabstop}; + $Text::Wrap::separator = ${ $mainSettings{modifyLineBreaks}{textWrapOptions} }{separator} + if ( ${ $mainSettings{modifyLineBreaks}{textWrapOptions} }{separator} ne '' ); + $Text::Wrap::break = ${ $mainSettings{modifyLineBreaks}{textWrapOptions} }{break} + if ${ $mainSettings{modifyLineBreaks}{textWrapOptions} }{break}; + $Text::Wrap::unexpand = ${ $mainSettings{modifyLineBreaks}{textWrapOptions} }{unexpand} + if ${ $mainSettings{modifyLineBreaks}{textWrapOptions} }{unexpand}; + $Text::Wrap::tabstop = ${ $mainSettings{modifyLineBreaks}{textWrapOptions} }{tabstop} + if ${ $mainSettings{modifyLineBreaks}{textWrapOptions} }{tabstop}; # clear the body, which will be updated with newly wrapped body ${$self}{body} = q(); - # loop back through the text wrap block storage - foreach my $textWrapBlockStorageValue (@textWrapBlockStorage){ - if ($textWrapBlockStorageValue =~ m/^\s*$blocksBeginWith/s or ${$self}{modifyLineBreaksYamlName} eq 'sentence') { + # loop back through the text wrap block storage + foreach my $textWrapBlockStorageValue (@textWrapBlockStorage) { + if ( $textWrapBlockStorageValue =~ m/^\s*$blocksBeginWith/s + or ${$self}{modifyLineBreaksYamlName} eq 'sentence' ) + { - # LIMIT is one greater than the maximum number of times EXPR may be split - my @textWrapBeforeEndWith = split(/($blocksEndBefore)/,$textWrapBlockStorageValue,2); - - # sentences need special treatment - if (${$self}{modifyLineBreaksYamlName} eq 'sentence'){ - @textWrapBeforeEndWith = (); - } + # LIMIT is one greater than the maximum number of times EXPR may be split + my @textWrapBeforeEndWith = split( /($blocksEndBefore)/, $textWrapBlockStorageValue, 2 ); - # if we have an occurence of blocksEndBefore, then grab the stuff before it - if (scalar @textWrapBeforeEndWith > 1){ - $textWrapBlockStorageValue = $textWrapBeforeEndWith[0]; - } + # sentences need special treatment + if ( ${$self}{modifyLineBreaksYamlName} eq 'sentence' ) { + @textWrapBeforeEndWith = (); + } - $logger->trace("TEXTWRAP BLOCK: $textWrapBlockStorageValue") if $is_tt_switch_active; + # if we have an occurence of blocksEndBefore, then grab the stuff before it + if ( scalar @textWrapBeforeEndWith > 1 ) { + $textWrapBlockStorageValue = $textWrapBeforeEndWith[0]; + } - # initiate the trailing comments storage - my $trailingComments = q(); + $logger->trace("TEXTWRAP BLOCK: $textWrapBlockStorageValue") if $is_tt_switch_active; - # grab all *internal* trailing comments from the block - while($textWrapBlockStorageValue =~ m|$trailingCommentRegExp|){ - $textWrapBlockStorageValue =~ s|(\h*$trailingCommentRegExp)||s; - $trailingComments .= $1; - } + # initiate the trailing comments storage + my $trailingComments = q(); - # determine if text wrapping will remove paragraph line breaks - my $removeBlockLineBreaks = ${$mainSettings{modifyLineBreaks}{textWrapOptions}}{removeBlockLineBreaks}; + # grab all *internal* trailing comments from the block + while ( $textWrapBlockStorageValue =~ m|$trailingCommentRegExp| ) { + $textWrapBlockStorageValue =~ s|(\h*$trailingCommentRegExp)||s; + $trailingComments .= $1; + } - # sentence remove line breaks is determined by removeSentenceLineBreaks - if (${$self}{modifyLineBreaksYamlName} eq 'sentence'){ - $removeBlockLineBreaks = ${$mainSettings{modifyLineBreaks}{oneSentencePerLine}}{removeSentenceLineBreaks}; - } + # determine if text wrapping will remove paragraph line breaks + my $removeBlockLineBreaks = ${ $mainSettings{modifyLineBreaks}{textWrapOptions} }{removeBlockLineBreaks}; - # remove internal line breaks - $textWrapBlockStorageValue =~ s/\R(?!\Z)/ /sg if $removeBlockLineBreaks; - - # convert multiple spaces into single - $textWrapBlockStorageValue =~ s/\h{2,}/ /sg if ${$mainSettings{modifyLineBreaks}{textWrapOptions}}{multipleSpacesToSingle}; - - # goal: get an accurate measurement of verbatim objects; - # - # example: - # Lorem \verb!x+y! ipsum dolor sit amet - # - # is represented as - # - # Lorem LTXIN-TK-VERBATIM1-END ipsum dolor sit amet - # - # so we *measure* the verbatim token and replace it with - # an appropriate-length string - # - # Lorem a2A41233rt ipsum dolor sit amet - # - # and then put the body back to - # - # Lorem LTXIN-TK-VERBATIM1-END ipsum dolor sit amet - # - # following the text wrapping - my @putVerbatimBackIn; - - # check body for verbatim and get measurements - if ($textWrapBlockStorageValue =~ m/$tokens{verbatim}/s and ${$mainSettings{modifyLineBreaks}{textWrapOptions}}{huge} eq "overflow"){ - - # reference: https://stackoverflow.com/questions/10336660/in-perl-how-can-i-generate-random-strings-consisting-of-eight-hex-digits - my @set = ('0' ..'9', 'A' .. 'Z', 'a' .. 'z'); - - # loop through verbatim objects - while( my ($verbatimID,$child)= each %verbatimStorage){ - my $verbatimThing = ${$child}{begin}.${$child}{body}.${$child}{end}; - - # if the object has line breaks, don't measure it - next if $verbatimThing =~ m/\R/s; - - if($textWrapBlockStorageValue =~m/$verbatimID/s){ - - # measure length - my $verbatimLength = &get_column_width($verbatimThing); - - # create temporary ID, and check that it is not contained in the body - my $verbatimTmpID = join '' => map $set[rand @set], 1 .. $verbatimLength; - while($textWrapBlockStorageValue=~m/$verbatimTmpID/s){ - $verbatimTmpID = join '' => map $set[rand @set], 1 .. $verbatimLength; - } - - # store for use after the text wrapping - push(@putVerbatimBackIn,{origVerbatimID=>$verbatimID,tmpVerbatimID=>$verbatimTmpID}); - - # make the substitution - $textWrapBlockStorageValue =~ s/$verbatimID/$verbatimTmpID/s; + # sentence remove line breaks is determined by removeSentenceLineBreaks + if ( ${$self}{modifyLineBreaksYamlName} eq 'sentence' ) { + $removeBlockLineBreaks + = ${ $mainSettings{modifyLineBreaks}{oneSentencePerLine} }{removeSentenceLineBreaks}; } - } - } - # perform the text wrap routine - $textWrapBlockStorageValue = wrap('','',$textWrapBlockStorageValue) if ${$mainSettings{modifyLineBreaks}{textWrapOptions}}{columns} > 0; + # remove internal line breaks + $textWrapBlockStorageValue =~ s/\R(?!\Z)/ /sg if $removeBlockLineBreaks; + + # convert multiple spaces into single + $textWrapBlockStorageValue =~ s/\h{2,}/ /sg + if ${ $mainSettings{modifyLineBreaks}{textWrapOptions} }{multipleSpacesToSingle}; + + # goal: get an accurate measurement of verbatim objects; + # + # example: + # Lorem \verb!x+y! ipsum dolor sit amet + # + # is represented as + # + # Lorem LTXIN-TK-VERBATIM1-END ipsum dolor sit amet + # + # so we *measure* the verbatim token and replace it with + # an appropriate-length string + # + # Lorem a2A41233rt ipsum dolor sit amet + # + # and then put the body back to + # + # Lorem LTXIN-TK-VERBATIM1-END ipsum dolor sit amet + # + # following the text wrapping + my @putVerbatimBackIn; + + # check body for verbatim and get measurements + if ( $textWrapBlockStorageValue =~ m/$tokens{verbatim}/s + and ${ $mainSettings{modifyLineBreaks}{textWrapOptions} }{huge} eq "overflow" ) + { + +# reference: https://stackoverflow.com/questions/10336660/in-perl-how-can-i-generate-random-strings-consisting-of-eight-hex-digits + my @set = ( '0' .. '9', 'A' .. 'Z', 'a' .. 'z' ); + + # loop through verbatim objects + while ( my ( $verbatimID, $child ) = each %verbatimStorage ) { + my $verbatimThing = ${$child}{begin} . ${$child}{body} . ${$child}{end}; + + # if the object has line breaks, don't measure it + next if $verbatimThing =~ m/\R/s; + + if ( $textWrapBlockStorageValue =~ m/$verbatimID/s ) { + + # measure length + my $verbatimLength = &get_column_width($verbatimThing); + + # create temporary ID, and check that it is not contained in the body + my $verbatimTmpID = join '' => map $set[ rand @set ], 1 .. $verbatimLength; + while ( $textWrapBlockStorageValue =~ m/$verbatimTmpID/s ) { + $verbatimTmpID = join '' => map $set[ rand @set ], 1 .. $verbatimLength; + } + + # store for use after the text wrapping + push( @putVerbatimBackIn, { origVerbatimID => $verbatimID, tmpVerbatimID => $verbatimTmpID } ); + + # make the substitution + $textWrapBlockStorageValue =~ s/$verbatimID/$verbatimTmpID/s; + } + } + } - # append trailing comments from WITHIN the block - $textWrapBlockStorageValue =~ s/\R?$/$trailingComments\n/s if ($trailingComments ne ''); + # perform the text wrap routine + $textWrapBlockStorageValue = wrap( '', '', $textWrapBlockStorageValue ) + if ${ $mainSettings{modifyLineBreaks}{textWrapOptions} }{columns} > 0; - # append blocksEndBefore and the stuff following it - if (scalar @textWrapBeforeEndWith > 1){ - $textWrapBlockStorageValue .= $textWrapBeforeEndWith[1].$textWrapBeforeEndWith[2]; - } + # append trailing comments from WITHIN the block + $textWrapBlockStorageValue =~ s/\R?$/$trailingComments\n/s if ( $trailingComments ne '' ); - # put blank line tokens on their own lines, should only happen when the following is used: - # blocksFollow: - # blankLine: 0 - while ($textWrapBlockStorageValue =~ m/^\H.*?$tokens{blanklines}/m ){ - $textWrapBlockStorageValue =~ s/^(\H.*?)$tokens{blanklines}/$1\n$tokens{blanklines}/m; - } + # append blocksEndBefore and the stuff following it + if ( scalar @textWrapBeforeEndWith > 1 ) { + $textWrapBlockStorageValue .= $textWrapBeforeEndWith[1] . $textWrapBeforeEndWith[2]; + } - # remove surrounding spaces from blank line tokens - $textWrapBlockStorageValue =~ s/^\h*$tokens{blanklines}\h*/$tokens{blanklines}/mg; + # put blank line tokens on their own lines, should only happen when the following is used: + # blocksFollow: + # blankLine: 0 + while ( $textWrapBlockStorageValue =~ m/^\H.*?$tokens{blanklines}/m ) { + $textWrapBlockStorageValue =~ s/^(\H.*?)$tokens{blanklines}/$1\n$tokens{blanklines}/m; + } + + # remove surrounding spaces from blank line tokens + $textWrapBlockStorageValue =~ s/^\h*$tokens{blanklines}\h*/$tokens{blanklines}/mg; - # put verbatim back in - $textWrapBlockStorageValue=~ s/${$_}{tmpVerbatimID}/${$_}{origVerbatimID}/s foreach (@putVerbatimBackIn); - } + # put verbatim back in + $textWrapBlockStorageValue =~ s/${$_}{tmpVerbatimID}/${$_}{origVerbatimID}/s foreach (@putVerbatimBackIn); + } - # update the body - ${$self}{body} .= $textWrapBlockStorageValue; + # update the body + ${$self}{body} .= $textWrapBlockStorageValue; } } diff --git a/Master/texmf-dist/scripts/latexindent/defaultSettings.yaml b/Master/texmf-dist/scripts/latexindent/defaultSettings.yaml index 13a78346598..c64dd5aeae5 100755 --- a/Master/texmf-dist/scripts/latexindent/defaultSettings.yaml +++ b/Master/texmf-dist/scripts/latexindent/defaultSettings.yaml @@ -1,4 +1,4 @@ -# defaultSettings.yaml for latexindent.pl, version 3.17.1, 2022-04-04 +# defaultSettings.yaml for latexindent.pl, version 3.17.2, 2022-04-14 # a script that aims to # beautify .tex, .sty, .cls files # @@ -197,6 +197,7 @@ lookForAlignDelims: drcases: 1 drcases*: 1 # nicematrix + NiceTabular: 1 NiceMatrix: 1 pNiceMatrix: 1 bNiceMatrix: 1 diff --git a/Master/texmf-dist/scripts/latexindent/latexindent.pl b/Master/texmf-dist/scripts/latexindent/latexindent.pl index be2d51b6f43..f75b8165a5f 100755 --- a/Master/texmf-dist/scripts/latexindent/latexindent.pl +++ b/Master/texmf-dist/scripts/latexindent/latexindent.pl @@ -1,5 +1,5 @@ #!/usr/bin/env perl -# latexindent.pl, version 3.17.1, 2022-04-04 +# latexindent.pl, version 3.17.2, 2022-04-14 # # 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 @@ -19,40 +19,40 @@ use strict; use warnings; -use FindBin; # help find defaultSettings.yaml -use Getopt::Long; # to get the switches/options/flags +use FindBin; # help find defaultSettings.yaml +use Getopt::Long; # to get the switches/options/flags # use lib to make sure that @INC contains the latexindent directory use lib $FindBin::RealBin; use LatexIndent::Document; # get the options -my %switches = (readLocalSettings=>0); +my %switches = ( readLocalSettings => 0 ); -GetOptions ( - "version|v"=>\$switches{version}, - "vversion|vv"=>\$switches{vversion}, - "silent|s"=>\$switches{silentMode}, - "trace|t"=>\$switches{trace}, - "ttrace|tt"=>\$switches{ttrace}, - "local|l:s"=>\$switches{readLocalSettings}, - "yaml|y=s"=>\$switches{yaml}, - "onlydefault|d"=>\$switches{onlyDefault}, - "overwrite|w"=>\$switches{overwrite}, - "overwriteIfDifferent|wd"=>\$switches{overwriteIfDifferent}, - "outputfile|o=s"=>\$switches{outputToFile}, - "modifylinebreaks|m"=>\$switches{modifyLineBreaks}, - "logfile|g=s"=>\$switches{logFileName}, - "help|h"=>\$switches{showhelp}, - "cruft|c=s"=>\$switches{cruftDirectory}, - "screenlog|sl"=>\$switches{screenlog}, - "replacement|r"=>\$switches{replacement}, - "onlyreplacement|rr"=>\$switches{onlyreplacement}, - "replacementrespectverb|rv"=>\$switches{replacementRespectVerb}, - "check|k"=>\$switches{check}, - "checkv|kv"=>\$switches{checkverbose}, - "lines|n=s"=>\$switches{lines}, - "GCString"=>\$switches{GCString}, +GetOptions( + "version|v" => \$switches{version}, + "vversion|vv" => \$switches{vversion}, + "silent|s" => \$switches{silentMode}, + "trace|t" => \$switches{trace}, + "ttrace|tt" => \$switches{ttrace}, + "local|l:s" => \$switches{readLocalSettings}, + "yaml|y=s" => \$switches{yaml}, + "onlydefault|d" => \$switches{onlyDefault}, + "overwrite|w" => \$switches{overwrite}, + "overwriteIfDifferent|wd" => \$switches{overwriteIfDifferent}, + "outputfile|o=s" => \$switches{outputToFile}, + "modifylinebreaks|m" => \$switches{modifyLineBreaks}, + "logfile|g=s" => \$switches{logFileName}, + "help|h" => \$switches{showhelp}, + "cruft|c=s" => \$switches{cruftDirectory}, + "screenlog|sl" => \$switches{screenlog}, + "replacement|r" => \$switches{replacement}, + "onlyreplacement|rr" => \$switches{onlyreplacement}, + "replacementrespectverb|rv" => \$switches{replacementRespectVerb}, + "check|k" => \$switches{check}, + "checkv|kv" => \$switches{checkverbose}, + "lines|n=s" => \$switches{lines}, + "GCString" => \$switches{GCString}, ); # conditionally load the GCString module @@ -66,16 +66,23 @@ eval "use Unicode::GCString" if $switches{GCString}; # in which case, the GetOptions routine mistakes myfile.tex # as the optional parameter to the l flag. # -# In such circumstances, we correct the mistake by assuming that +# In such circumstances, we correct the mistake by assuming that # the only argument is the file to be indented, and place it in @ARGV -if($switches{readLocalSettings} and scalar(@ARGV) < 1) { - push(@ARGV,$switches{readLocalSettings}); +if ( $switches{readLocalSettings} and scalar(@ARGV) < 1 ) { + push( @ARGV, $switches{readLocalSettings} ); $switches{readLocalSettings} = ''; } # allow STDIN as input, if a filename is not present unshift( @ARGV, '-' ) unless @ARGV; -my $document = bless ({name=>"mainDocument",modifyLineBreaksYamlName=>"mainDocument",switches=>\%switches},"LatexIndent::Document"); +my $document = bless( + { + name => "mainDocument", + modifyLineBreaksYamlName => "mainDocument", + switches => \%switches + }, + "LatexIndent::Document" +); $document->latexindent( \@ARGV ); exit(0); |