Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
14 / 14 |
|
100.00% |
2 / 2 |
CRAP | |
100.00% |
1 / 1 |
HeadingCounter | |
100.00% |
14 / 14 |
|
100.00% |
2 / 2 |
6 | |
100.00% |
1 / 1 |
incrementAndGet | |
100.00% |
11 / 11 |
|
100.00% |
1 / 1 |
4 | |||
incrementAndGetTopLevel | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 |
1 | <?php |
2 | |
3 | namespace MediaWiki\Extension\Collection; |
4 | |
5 | use LogicException; |
6 | |
7 | /** |
8 | * Helper class for counting sections and displaying current section number. |
9 | * The numbering is done in a way to avoid showing zeroes in the counter: |
10 | * e.g. for "<h2/><h4/><h2/><h3/>" the result will be "1 1.1 2 2.1" and not "1 1.0.1 2 2.1". |
11 | */ |
12 | class HeadingCounter { |
13 | |
14 | /** |
15 | * List of current numbers, left is highest-level. |
16 | * @var int[] level => count |
17 | */ |
18 | private $headingNumbers = []; |
19 | |
20 | /** |
21 | * Increment the section counter and get the number of the new section. |
22 | * @param int $level Level of the current section. Smaller number means higher in the DOM; |
23 | * other than that the class is agnostic to what level numbering scheme is used. E.g. |
24 | * could be 1 for h1, 2 for h2 etc. |
25 | * @return string |
26 | */ |
27 | public function incrementAndGet( $level ) { |
28 | $top = reset( $this->headingNumbers ); |
29 | $this->headingNumbers = array_filter( $this->headingNumbers, |
30 | static function ( $l ) use ( $level ) { |
31 | return $l <= $level; |
32 | }, ARRAY_FILTER_USE_KEY ); |
33 | if ( !$this->headingNumbers && $top ) { |
34 | // The new section is higher than all previous ones. Let's inherit the count from the |
35 | // previous top section. E.g. for "<h3/><h2/>" we want the section numbers to be |
36 | // "1 2", not "1 1". |
37 | $this->headingNumbers[$level] = $top; |
38 | } |
39 | if ( isset( $this->headingNumbers[$level] ) ) { |
40 | $this->headingNumbers[$level]++; |
41 | } else { |
42 | $this->headingNumbers[$level] = 1; |
43 | } |
44 | return implode( '.', $this->headingNumbers ); |
45 | } |
46 | |
47 | /** |
48 | * Increment section number for a top-level section and get new value. |
49 | * Calls to this method must be preceded with at least one incrementAndGet() call. |
50 | * Intended for the Contributors section the level of which depends on whether the book |
51 | * has chapters and/or multiple articles. |
52 | * @return string |
53 | */ |
54 | public function incrementAndGetTopLevel() { |
55 | if ( !$this->headingNumbers ) { |
56 | throw new LogicException( __METHOD__ . ' called with calling increment() first' ); |
57 | } |
58 | return $this->incrementAndGet( array_keys( $this->headingNumbers )[0] ); |
59 | } |
60 | |
61 | } |