Subversion Repositories Applications.papyrus

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
248 jpm 1
<?php
2
 
3
/**
4
*
5
* Parse for block-quoted text.
6
*
7
* Find source text marked as a blockquote, identified by any number of
8
* greater-than signs '>' at the start of the line, followed by a space,
9
* and then the quote text; each '>' indicates an additional level of
10
* quoting.
11
*
12
* $Id: Blockquote.php,v 1.1 2005-01-20 19:43:20 jpm Exp $
13
*
14
* @author Paul M. Jones <pmjones@ciaweb.net>
15
*
16
* @package Text_Wiki
17
*
18
*/
19
 
20
class Text_Wiki_Parse_Blockquote extends Text_Wiki_Parse {
21
 
22
 
23
    /**
24
    *
25
    * Regex for parsing the source text.
26
    *
27
    * @access public
28
    *
29
    * @var string
30
    *
31
    * @see parse()
32
    *
33
    */
34
 
35
    var $regex = '/\n((\>).*\n)(?!(\>))/Us';
36
 
37
 
38
    /**
39
    *
40
    * Generates a replacement for the matched text.
41
    *
42
    * Token options are:
43
    *
44
    * 'type' =>
45
    *     'start' : the start of a blockquote
46
    *     'end'   : the end of a blockquote
47
    *
48
    * 'level' => the indent level (0 for the first level, 1 for the
49
    * second, etc)
50
    *
51
    * @access public
52
    *
53
    * @param array &$matches The array of matches from parse().
54
    *
55
    * @return A series of text and delimited tokens marking the different
56
    * list text and list elements.
57
    *
58
    */
59
 
60
    function process(&$matches)
61
    {
62
        // the replacement text we will return to parse()
63
        $return = '';
64
 
65
        // the list of post-processing matches
66
        $list = array();
67
 
68
        // $matches[1] is the text matched as a list set by parse();
69
        // create an array called $list that contains a new set of
70
        // matches for the various list-item elements.
71
        preg_match_all(
72
            '=^(\>+) (.*\n)=Ums',
73
            $matches[1],
74
            $list,
75
            PREG_SET_ORDER
76
        );
77
 
78
        // a stack of starts and ends; we keep this so that we know what
79
        // indent level we're at.
80
        $stack = array();
81
 
82
        // loop through each list-item element.
83
        foreach ($list as $key => $val) {
84
 
85
            // $val[0] is the full matched list-item line
86
            // $val[1] is the number of initial '>' chars (indent level)
87
            // $val[2] is the quote text
88
 
89
            // we number levels starting at 1, not zero
90
            $level = strlen($val[1]);
91
 
92
            // get the text of the line
93
            $text = $val[2];
94
 
95
            // add a level to the list?
96
            while ($level > count($stack)) {
97
 
98
                // the current indent level is greater than the number
99
                // of stack elements, so we must be starting a new
100
                // level.  push the new level onto the stack with a
101
                // dummy value (boolean true)...
102
                array_push($stack, true);
103
 
104
                $return .= "\n";
105
 
106
                // ...and add a start token to the return.
107
                $return .= $this->wiki->addToken(
108
                    $this->rule,
109
                    array(
110
                        'type' => 'start',
111
                        'level' => $level - 1
112
                    )
113
                );
114
 
115
                $return .= "\n\n";
116
            }
117
 
118
            // remove a level?
119
            while (count($stack) > $level) {
120
 
121
                // as long as the stack count is greater than the
122
                // current indent level, we need to end list types.
123
                // continue adding end-list tokens until the stack count
124
                // and the indent level are the same.
125
                array_pop($stack);
126
 
127
                $return .= "\n\n";
128
 
129
                $return .= $this->wiki->addToken(
130
                    $this->rule,
131
                    array (
132
                        'type' => 'end',
133
                        'level' => count($stack)
134
                    )
135
                );
136
 
137
                $return .= "\n";
138
            }
139
 
140
            // add the line text.
141
            $return .= $text;
142
        }
143
 
144
        // the last line may have been indented.  go through the stack
145
        // and create end-tokens until the stack is empty.
146
        $return .= "\n";
147
 
148
        while (count($stack) > 0) {
149
            array_pop($stack);
150
            $return .= $this->wiki->addToken(
151
                $this->rule,
152
                array (
153
                    'type' => 'end',
154
                    'level' => count($stack)
155
                )
156
            );
157
        }
158
 
159
        // we're done!  send back the replacement text.
160
        return "\n$return\n\n";
161
    }
162
}
163
?>