1<?php
2/**
3 * Plugin nspages : Displays nicely a list of the pages of a namespace
4 *
5 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
6 * @author  Guillaume Turri <guillaume.turri@gmail.com>
7 */
8if(!defined('DOKU_INC')) die();
9
10class optionParser {
11
12    static function checkRegEx(&$match, $pattern, &$arrayAffected) {
13        optionParser::preg_match_all_wrapper($pattern, $match, $found);
14        foreach($found as $regex) {
15            $arrayAffected[] = $regex[1];
16            $match           = optionParser::_removeFromMatch($regex[0], $match);
17        }
18    }
19
20    /**
21     * Check if a given option has been given, and remove it from the initial string
22     *
23     * @param string $match The string match by the plugin
24     * @param string $pattern The pattern which activate the option
25     * @param mixed  $varAffected The variable which will memorise the option
26     * @param mixed  $valIfFound the value affected to the previous variable if the option is found
27     */
28    static function checkOption(&$match, $pattern, &$varAffected, $valIfFound) {
29        if(optionParser::preg_match_wrapper($pattern, $match, $found)) {
30            $varAffected = $valIfFound;
31            $match       = optionParser::_removeFromMatch($found[0], $match);
32        }
33    }
34
35    static function checkRecurse(&$match, &$varAffected){
36        if(optionParser::preg_match_wrapper('r *=? *\"?([[:digit:]]*)\"?', $match, $found)) {
37            if($found[1] != '') {
38                $varAffected = (int) $found[1];
39            } else {
40                $varAffected = 0; //no limit
41            }
42            $match = optionParser::_removeFromMatch($found[0], $match);
43        }
44    }
45
46    static function checkNbColumns(&$match, &$varAffected){
47        if(optionParser::preg_match_wrapper("nb?Cols? *=? *\"?([[:digit:]]*)\"?", $match, $found)) {
48            if($found[1] != '') {
49                $varAffected = max((int) $found[1], 1);
50            }
51            $match = optionParser::_removeFromMatch($found[0], $match);
52        }
53    }
54
55    static function checkNbItemsMax(&$match, &$varAffected){
56        if(optionParser::preg_match_wrapper("nb?Items?Max *=? *\"?([[:digit:]]*)\"?", $match, $found)) {
57            if($found[1] != '') {
58                $varAffected = max((int) $found[1], 1);
59            }
60            $match = optionParser::_removeFromMatch($found[0], $match);
61        }
62    }
63
64    static function checkAnchorName(&$match, &$varAffected){
65        if(optionParser::preg_match_wrapper("anchorName *=? *\"?([[:alnum:]]+)\"?", $match, $found)) {
66            $varAffected = $found[1];
67            $match = optionParser::_removeFromMatch($found[0], $match);
68        }
69    }
70
71    static function checkSimpleStringArgument(&$match, &$varAffected, $plugin, $argumentName){
72        if(optionParser::preg_match_wrapper($argumentName . " *= *\"([^\"]*)\"", $match, $found)) {
73            $varAffected = $found[1];
74            $match       = optionParser::_removeFromMatch($found[0], $match);
75        } else {
76            $varAffected = null;
77        }
78    }
79
80    static function checkDictOrder(&$match, &$varAffected, $plugin){
81        if(optionParser::preg_match_wrapper("dict(?:ionary)?Order *= *\"([^\"]*)\"", $match, $found)) {
82            $varAffected = $found[1];
83            $match       = optionParser::_removeFromMatch($found[0], $match);
84        } else {
85            $varAffected = null;
86        }
87    }
88
89    static function checkExclude(&$match, &$excludedPages, &$excludedNs, &$excludeSelfPage){
90        //--Looking if the syntax -exclude[item1 item2] has been used
91        if(optionParser::preg_match_wrapper("exclude:\[(.*)\]", $match, $found)) {
92            $match = optionParser::_removeFromMatch($found[0], $match);
93            self::_addListOfItemsToExclude(explode(' ', $found[1]), $excludedPages, $excludedNs);
94        }
95
96        //--Checking if specified subnamespaces have to be excluded
97        optionParser::preg_match_all_wrapper("exclude:([^[ <>]*):", $match, $found);
98        foreach($found as $subns) {
99            $excludedNs[] = $subns[1];
100            $match        = optionParser::_removeFromMatch($subns[0], $match);
101        }
102
103        //--Checking if specified pages have to be excluded
104        optionParser::preg_match_all_wrapper("exclude:([^[ <>]*)", $match, $found);
105        foreach($found as $page) {
106            $excludedPages[] = $page[1];
107            $match           = optionParser::_removeFromMatch($page[0], $match);
108        }
109
110        //--Looking if the current page has to be excluded
111        if(optionParser::preg_match_wrapper("exclude", $match, $found)) {
112            $excludeSelfPage = true;
113            $match           = optionParser::_removeFromMatch($found[0], $match);
114        }
115    }
116
117    static function checkGlobalExclude($globalExclude, &$excludedPages, &$excludedNs) {
118        if(!empty($globalExclude)) {
119          self::_addListOfItemsToExclude(explode(',', $globalExclude), $excludedPages, $excludedNs);
120        }
121    }
122
123    private static function _addListOfItemsToExclude($excludeList, &$excludedPages, &$excludedNs) {
124       foreach($excludeList as $exclude) {
125           $exclude = trim($exclude);
126           if($exclude[strlen($exclude) - 1] === ':') { //not utf8_strlen() on purpose
127               $excludedNs[] = utf8_substr($exclude, 0, -1);
128           } else {
129               $excludedPages[] = $exclude;
130           }
131       }
132    }
133
134    static function checkActualTitle(&$match, &$varAffected){
135        $foundOption = false;
136        if ( optionParser::preg_match_wrapper("actualTitle *= *([[:digit:]])", $match, $found) ){
137            $varAffected = $found[1];
138            $foundOption = true;
139        } else if ( optionParser::preg_match_wrapper("actualTitle", $match, $found) ){
140            $varAffected = 2;
141            $foundOption = true;
142        }
143
144        if ($foundOption) {
145            $match = optionParser::_removeFromMatch($found[0], $match);
146        }
147    }
148
149    static private function preg_match_wrapper($pattern, $subject, &$matches){
150        return preg_match('/\s-' . $pattern . '/i', $subject, $matches);
151    }
152
153    static private function preg_match_all_wrapper($pattern, $subject, &$matches){
154        return preg_match_all('/\s-' . $pattern . '/i', $subject, $matches, PREG_SET_ORDER);
155    }
156
157    static private function _removeFromMatch($matched, $match){
158        $matched = trim($matched); // to handle the case of the option "-r" which already matches an extra whitespace
159        return substr(str_replace($matched.' ', ' ', $match.' '), 0, -1);
160    }
161}
162