summaryrefslogtreecommitdiff
path: root/support/latexindent/LatexIndent/UnNamedGroupingBracesBrackets.pm
blob: eea6ee6747aece014fb42d7a27c0e7bb480798af (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
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
#	(at your option) any later version.
#
#	This program is distributed in the hope that it will be useful,
#	but WITHOUT ANY WARRANTY; without even the implied warranty of
#	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#	GNU General Public License for more details.
#
#	See http://www.gnu.org/licenses/.
#
#	Chris Hughes, 2017
#
#	For all communication, please visit: https://github.com/cmhughes/latexindent.pl
use strict;
use warnings;
use LatexIndent::Tokens qw/%tokens/;
use LatexIndent::GetYamlSettings qw/%masterSettings/;
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 $unNamedGroupingBracesCounter;
our $un_named_grouping_braces_RegExp;
our $un_named_grouping_braces_RegExp_trailing_comment; 

sub construct_unnamed_grouping_braces_brackets_regexp{
    my $self = shift;

    # grab the arguments regexp
    my $optAndMandRegExp = $self->get_arguments_regexp;

    # blank line token
    my $blankLineToken = $tokens{blanklines};

    # arguments Before, by default, includes beamer special and numbered arguments, for example #1 #2, etc
    my $argumentsBefore = qr/${${$masterSettings{fineTuning}}{arguments}}{before}/;
    my $UnNamedGroupingFollowRegExp = qr/${${$masterSettings{fineTuning}}{UnNamedGroupingBracesBrackets}}{follow}/;

    # store the regular expresssion for matching and replacing 
    $un_named_grouping_braces_RegExp = qr/
                  # NOT
                  (?!
                      (?:
                        (?:(?<!\\)\]) 
                        |
                        (?:(?<!\\)\}) 
                      )
                      (?:\h|\R|$blankLineToken|$trailingCommentRegExp|$argumentsBefore)*  # 0 or more h-space, blanklines, trailing comments
                  )
                  # END of NOT
                  (
                     (?:
                        $UnNamedGroupingFollowRegExp # starting with { OR [ OR , OR & OR ) OR ( OR $
                     )
                     \h*
                  )                                  # $1 into beginning bit
                  (\R*)                              # $2 linebreaksAtEnd of begin
                  ($optAndMandRegExp)                # $3 mand|opt arguments (at least one) stored into body
                  (\R)?                              # $6 linebreak 
                /sx;

    $un_named_grouping_braces_RegExp_trailing_comment = qr/$un_named_grouping_braces_RegExp(\h*)((?:$trailingCommentRegExp\h*)*)?/; 
}

sub create_unique_id{
    my $self = shift;

    $unNamedGroupingBracesCounter++;
    ${$self}{id} = "$tokens{UnNamedGroupingBracesBrackets}$unNamedGroupingBracesCounter";
    return;
}

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
    $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)
    ${$self}{body} =~ s/(.*?)(\{|\[)/$2/s;
    ${$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);
    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, 
    #       test-cases/namedGroupingBracesBrackets/special-characters-minimal-blank-lines-m-switch.tex
    #   compared to
    #       test-cases/namedGroupingBracesBrackets/special-characters-minimal-blank-lines-default.tex
    my $self = shift;

    # blank line token
    my $blankLineToken = $tokens{blanklines};

    # if the body begins with 2 or more blank line tokens
    if(${$self}{body} =~ m/^((?:$blankLineToken\R){2,})/s){

        # remove them
        ${$self}{body} =~ s/^((?:$blankLineToken\R)+)//s;

        # store
        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
    }
    return;
}

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};
        }
    }
    return
}

1;