Passed
Branch master (43d553)
by Sebastian
02:54
created

ConvertHelper_TabsNormalizer::setTabSize()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 2
c 1
b 0
f 0
dl 0
loc 5
rs 10
cc 1
nc 1
nop 1
1
<?php
2
/**
3
 * File containing the {@see AppUtils\ConvertHelper_TabsNormalizer} class.
4
 *
5
 * @package Application Utils
6
 * @subpackage ConvertHelper
7
 * @see AppUtils\ConvertHelper_TabsNormalizer
8
 */
9
declare(strict_types=1);
10
11
namespace AppUtils;
12
13
/**
14
 * Reduces tabbed indentation in a string so the text
15
 * is left-adjusted.
16
 *
17
 * @package Application Utils
18
 * @subpackage ConvertHelper
19
 * @author Sebastian Mordziol <[email protected]>
20
 */
21
class ConvertHelper_TabsNormalizer
22
{
23
   /**
24
    * @var integer
25
    */
26
    protected $max = 0;
27
    
28
   /**
29
    * @var integer
30
    */
31
    protected $min = PHP_INT_MAX;
32
    
33
   /**
34
    * @var bool
35
    */
36
    protected $tabs2spaces = false;
37
    
38
   /**
39
    * @var array
40
    */
41
    protected $lines = array();
42
43
   /**
44
    * @var string
45
    */
46
    protected $eol = '';
47
    
48
   /**
49
    * @var integer
50
    */
51
    protected $tabSize = 4;
52
    
53
   /**
54
    * Whether to enable or disable the conversion
55
    * of tabs to spaces.
56
    * 
57
    * @param bool $enable
58
    * @return ConvertHelper_TabsNormalizer
59
    */
60
    public function convertTabsToSpaces(bool $enable=true) : ConvertHelper_TabsNormalizer
61
    {
62
        $this->tabs2spaces = $enable;
63
        
64
        return $this;
65
    }
66
    
67
   /**
68
    * Sets the size of a tab, in spaces. Used to convert tabs
69
    * from spaces and the other way around. Defaults to 4.
70
    * 
71
    * @param int $amountSpaces
72
    * @return ConvertHelper_TabsNormalizer
73
    */
74
    public function setTabSize(int $amountSpaces) : ConvertHelper_TabsNormalizer
75
    {
76
        $this->tabSize = $amountSpaces;
77
        
78
        return $this;
79
    }
80
    
81
   /**
82
    * Normalizes tabs in the specified string by indenting everything
83
    * back to the minimum tab distance. With the second parameter,
84
    * tabs can optionally be converted to spaces as well (recommended
85
    * for HTML output).
86
    *
87
    * @param string $string
88
    * @return string
89
    */
90
    public function normalize(string $string) : string
91
    {
92
        $this->splitLines($string);
93
        $this->countOccurrences();
94
        
95
        $result = $this->_normalize();
96
        
97
        if($this->tabs2spaces) 
98
        {
99
            $result = ConvertHelper::tabs2spaces($result, $this->tabSize);
100
        }
101
        
102
        $this->lines = array(); // clear memory
103
        
104
        return $result;
105
    }
106
    
107
    protected function splitLines(string $string) : void
108
    {
109
        $eol = ConvertHelper::detectEOLCharacter($string);
110
        
111
        if($eol !== null) 
112
        {
113
            $this->eol = $eol->getCharacter();
114
        }
115
        
116
        // convert any existing space based tabs to actual tabs
117
        $string = ConvertHelper::spaces2tabs($string, $this->tabSize);
118
        
119
        // explode only using \n, as the lines will be trimmed and
120
        // then imploded again with the EOL char: this way it is EOL
121
        // independent.
122
        $this->lines = explode("\n", $string);
123
    }
124
    
125
    protected function _normalize() : string
126
    {
127
        $converted = array();
128
        
129
        foreach($this->lines as $line) 
130
        {
131
            $amount = substr_count($line, "\t") - $this->min;
132
            
133
            $line = trim($line, "\n\r\t");
134
            
135
            if($amount >= 1) 
136
            {
137
                $line = str_repeat("\t", $amount) . $line;
138
            }
139
            
140
            $converted[] = $line;
141
        }
142
        
143
        return implode($this->eol, $converted);
144
    }
145
    
146
   /**
147
    * Finds out the minimum and maximum amount of 
148
    * tabs in the string.
149
    */
150
    protected function countOccurrences() : void
151
    {
152
        foreach($this->lines as $line) 
153
        {
154
            $amount = substr_count($line, "\t");
155
            
156
            if($amount > $this->max) 
157
            {
158
                $this->max = $amount;
159
                continue;
160
            }
161
            
162
            if($amount > 0 && $amount < $this->min) 
163
            {
164
                $this->min = $amount;
165
            }
166
        }
167
        
168
        if($this->min === PHP_INT_MAX) {
169
            $this->min = 0;
170
        }
171
    }
172
}
173