1: <?php
2: class Nag_QuickParser
3: {
4: protected $_indentStack;
5:
6: public function __construct($stack = null)
7: {
8: if ($stack === null) { $stack = new Horde_Support_Stack(); }
9: $this->_indentStack = $stack;
10: }
11:
12: public function parse($text)
13: {
14: $text = str_replace("\t", ' ', $text);
15: $lines = preg_split('/[\r\n]+/', $text, -1, PREG_SPLIT_NO_EMPTY);
16:
17: $parents = array();
18: $tasks = array();
19: foreach ($lines as $line) {
20: $line = rtrim($line);
21: if (preg_match('/^\s*$/', $line)) { continue; }
22:
23: $indented = preg_match('/^([*-\s]+)(.*)$/', $line, $matches);
24: if (!$indented) {
25: $tasks[] = $line;
26: $parents[$this->_indentStack->peek()] = count($tasks) - 1;
27: } else {
28: $line = $matches[2];
29: $indent = strlen($matches[1]);
30: if ($indent == $this->_indentStack->peek()) {
31: $parent = $parents[$this->_indentStack->peek(2)];
32: $tasks[] = array($line, 'parent' => $parent);
33: } elseif ($indent > $this->_indentStack->peek()) {
34: $parent = $parents[$this->_indentStack->peek()];
35: $this->_indentStack->push($indent);
36: $tasks[] = array($line, 'parent' => $parent);
37: $parents[$this->_indentStack->peek()] = count($tasks) - 1;
38: } else {
39: while ($this->_indentStack->pop() > $indent);
40:
41: $parents[$indent] = $parents[$this->_indentStack->peek()];
42: $this->_indentStack->pop(); $this->_indentStack->push($indent);
43: $parent = $parents[$this->_indentStack->peek()];
44: if ($parent !== null) {
45: $tasks[] = array($line, 'parent' => $parent);
46: } else {
47: $tasks[] = $line;
48: }
49: $parents[$this->_indentStack->peek()] = count($tasks) - 1;
50: }
51: }
52: }
53:
54: return $tasks;
55: }
56: }
57: