2 // PukiWiki - Yet another WikiWikiWeb clone.
4 // Copyright 2003-2016 PukiWiki Development Team
5 // License: GPL v2 or (at your option) any later version
7 // Parse a PukiWiki page as a configuration page
10 * $obj = new Config('plugin/plugin_name/')
12 * $array = & $obj->get($title);
13 * $array[] = array(4, 5, 6); // Add - directly
14 * $obj->add($title, array(4, 5, 6)); // Add - method of Config object
15 * $array = array(1=>array(1, 2, 3)); // Replace - directly
16 * $obj->put($title, array(1=>array(1, 2, 3)); // Replace - method of Config object
17 * $obj->put_values($title, NULL); // Delete
21 // Fixed prefix of configuration-page's name
22 define('PKWK_CONFIG_PREFIX', ':config/');
24 // Configuration-page manager
27 var $name, $page; // Page name
30 function Config($name)
32 $this->__construct($name);
34 function __construct($name)
37 $this->page = PKWK_CONFIG_PREFIX . $name;
40 // Load the configuration-page
43 if (! is_page($this->page)) return FALSE;
45 $this->objs = array();
46 $obj = new ConfigTable('');
49 foreach (get_source($this->page) as $line) {
50 if ($line == '') continue;
52 $head = $line{0}; // The first letter
53 $level = strspn($line, $head);
56 $obj->add_line($line);
58 } else if ($head == '*') {
59 // Cut fixed-heading anchors
60 $line = preg_replace('/^(\*{1,3}.*)\[#[A-Za-z][\w-]+\](.*)$/', '$1$2', $line);
63 $this->objs[$obj->title] = $obj;
64 $obj = new ConfigTable($line);
66 if (! is_a($obj, 'ConfigTable_Direct'))
67 $obj = new ConfigTable_Direct('', $obj);
71 } else if ($head == '-' && $level > 1) {
72 if (! is_a($obj, 'ConfigTable_Direct'))
73 $obj = new ConfigTable_Direct('', $obj);
74 $obj->add_value($line);
76 } else if ($head == '|' && preg_match('/^\|(.+)\|\s*$/', $line, $matches)) {
78 if (! is_a($obj, 'ConfigTable_Sequential'))
79 $obj = new ConfigTable_Sequential('', $obj);
80 // Trim() each table cell
81 $obj->add_value(array_map('trim', explode('|', $matches[1])));
83 $obj->add_line($line);
86 $this->objs[$obj->title] = $obj;
92 function & get($title)
94 $obj = & $this->get_object($title);
98 // Set an array (Override)
99 function put($title, $values)
101 $obj = & $this->get_object($title);
102 $obj->values = $values;
106 function add($title, $value)
108 $obj = & $this->get_object($title);
109 $obj->values[] = $value;
112 // Get an object (or create it)
113 function & get_object($title)
115 if (! isset($this->objs[$title]))
116 $this->objs[$title] = new ConfigTable('*' . trim($title) . "\n");
117 return $this->objs[$title];
122 page_write($this->page, $this->toString());
128 foreach ($this->objs as $title=>$obj)
129 $retval .= $obj->toString();
134 // Class holds array values
137 var $title = ''; // Table title
138 var $before = array(); // Page contents (except table ones)
139 var $after = array(); // Page contents (except table ones)
140 var $values = array(); // Table contents
142 function ConfigTable($title, $obj = NULL)
144 $this->__construct($title, $obj);
146 function __construct($title, $obj = NULL)
149 $this->title = $obj->title;
150 $this->before = array_merge($obj->before, $obj->after);
152 $this->title = trim(substr($title, strspn($title, '*')));
153 $this->before[] = $title;
157 // Addi an explanation
158 function add_line($line)
160 $this->after[] = $line;
165 return join('', $this->before) . join('', $this->after);
169 class ConfigTable_Sequential extends ConfigTable
172 function add_value($value)
174 $this->values[] = (count($value) == 1) ? $value[0] : $value;
179 $retval = join('', $this->before);
180 if (is_array($this->values)) {
181 foreach ($this->values as $value) {
182 $value = is_array($value) ? join('|', $value) : $value;
183 $retval .= '|' . $value . '|' . "\n";
186 $retval .= join('', $this->after);
191 class ConfigTable_Direct extends ConfigTable
193 var $_keys = array(); // Used at initialization phase
195 function set_key($line)
197 $level = strspn($line, '*');
198 $this->_keys[$level] = trim(substr($line, $level));
202 function add_value($line)
204 $level = strspn($line, '-');
205 $arr = & $this->values;
206 for ($n = 2; $n <= $level; $n++)
207 $arr = & $arr[$this->_keys[$n]];
208 $arr[] = trim(substr($line, $level));
211 function toString($values = NULL, $level = 2)
214 $root = ($values === NULL);
216 $retval = join('', $this->before);
217 $values = & $this->values;
219 foreach ($values as $key=>$value) {
220 if (is_array($value)) {
221 $retval .= str_repeat('*', $level) . $key . "\n";
222 $retval .= $this->toString($value, $level + 1);
224 $retval .= str_repeat('-', $level - 1) . $value . "\n";
227 if ($root) $retval .= join('', $this->after);