Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
 
3
/**
4
 * Creole parser implementation
5
 *
6
 * @author Josep Arús
7
 *
8
 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
9
 * @package mod_wiki
10
 */
11
 
12
include_once("wikimarkup.php");
13
 
14
class creole_parser extends wiki_markup_parser {
15
 
16
    protected $blockrules = array(
17
        'nowiki' => array(
18
            'expression' => "/^\{\{\{(.*?)\}\}\}/ims",
19
            'tags' => array(),
20
            'token' => array('{{{', '}}}')
21
        ),
22
        'header' => array(
23
            'expression' => "/^\ *(={1,6})\ *(.+?)=*\ *$/ims",
24
            'tags' => array(), //none
25
            'token' => '='
26
        ),
27
        'table' => array(
28
            'expression' => "/^(?:\|.*?\|\ *\n)+/ims"
29
        ),
30
        'line_break' => array(
31
            'expression' => "/^----\s*$/im",
32
            'token' => '----',
33
            'tags' => array()
34
        ),
35
        'list' => array(
36
            'expression' => "/((?:^\ *[\*#][^\*#]\ *.+?)(?:^\ *[\*#]{1,5}\ *.+?)*)(\n\s*(?:\n|<(?:h\d|pre|table|tbody|thead|tr|th|td|ul|li|ol|hr)))/ims",
37
            'tags' => array(),
38
            'token' => array('*', '#')
39
        ),
40
        'paragraph' => array(
41
            'expression' => "/^\ *((?:<(?!\ *\/?(?:h\d|pre|table|tbody|thead|tr|th|td|ul|li|ol|hr)\ *\/?>)|[^<\s]).+?)\n\s*\n/ims",
42
            //not specified -> all tags (null or unset)
43
            'tag' => 'p'
44
        )
45
    );
46
 
47
    protected $tagrules = array(
48
        'nowiki' => array(
49
            'expression' => "/\{\{\{(.*?)\}\}\}/is",
50
            'token' => array('{{{', '}}}')
51
        ),
52
        'image' => array(
53
            'expression' => "/\~?\{\{(.+)\|(.+)\}\}/i",
54
            'tags' => array(),
55
            'token' => array('{{', '|Alt}}')
56
        ),
57
        'link' => array(
58
            'expression' => "/\~?\[\[(.+?)\]\]/is",
59
            'tag' => 'a',
60
            'token' => array('[[', ']]')
61
        ),
62
        'url' => array(
63
            'expression' => "/\~?(?<!=\")((?:https?|ftp):\/\/[^\s\n]+[^,\.\?!:;\"\'\n\ ])/is",
64
            'tag' => 'a',
65
            'token' => "http://"
66
        ),
67
        'line_break' => array(
68
            'expression' => "/\\\\\\\\/",
69
            'tag' => 'br',
70
            'simple' => true,
71
            'token' => '----'
72
        ),
73
        'bold' => array(
74
            'expression' => "/\*\*(.*?)(?:\*\*|$)/is",
75
            'tag' => 'strong',
76
            'token' => array('**', '**')
77
        ),
78
        'italic' => array(
79
            'expression' => "#(?<!http:|https:|ftp:)//(.+?)(?<!http:|https:|ftp:)//#is",
80
            'tag' => 'em',
81
            'token' => array('//', '//')
82
        )
83
    );
84
 
85
    /**
86
     * Block hooks
87
     */
88
 
89
    protected function before_parsing() {
90
        $this->string = htmlspecialchars($this->string, ENT_COMPAT);
91
        parent::before_parsing();
92
    }
93
 
94
    public function get_section($header, $text, $clean = false) {
95
        // The requested header is likely to have been passed to htmlspecialchars in
96
        // self::before_parsing(), therefore we should decode it when looking for it.
97
        return parent::get_section(htmlspecialchars_decode($header, ENT_COMPAT), $text, $clean);
98
    }
99
 
100
    protected function header_block_rule($match) {
101
        $num = strlen($match[1]);
102
 
103
        $text = trim($match[2]);
104
 
105
        $text = preg_replace("/\s*={1,$num}$/im", "", $text);
106
 
107
        return $this->generate_header($text, $num);
108
    }
109
 
110
    /**
111
     * Table generation
112
     */
113
 
114
    protected function table_block_rule($match) {
115
 
116
        $rows = explode("\n", $match[0]);
117
        $table = array();
118
        foreach($rows as $r) {
119
            if(empty($r)) {
120
                continue;
121
            }
122
            $rawcells = explode("|", $r);
123
            $cells = array();
124
 
125
            array_shift($rawcells);
126
            array_pop($rawcells);
127
 
128
            foreach($rawcells as $c) {
129
                if(!empty($c)) {
130
                    if($c[0] == "=") {
131
                        $type = 'header';
132
                        $c = substr($c, 1);
133
                    }
134
                    else {
135
                        $type = 'normal';
136
                    }
137
                    $this->rules($c);
138
                    $cells[] = array($type, $c);
139
                }
140
            }
141
            $table[] = $cells;
142
        }
143
 
144
        return $this->generate_table($table);
145
    }
146
 
147
    protected function paragraph_block_rule($match) {
148
        $text = $match[1];
149
        foreach($this->tagrules as $tr) {
150
            if(isset($tr['token'])) {
151
                if(is_array($tr['token'])) {
152
                    $this->escape_token_string($text, $tr['token'][0]);
153
                    $this->escape_token_string($text, $tr['token'][1]);
154
                }
155
                else {
156
                    $this->escape_token_string($text, $tr['token']);
157
                }
158
            }
159
        }
160
        $this->escape_token_string($text, "~");
161
 
162
        return $text;
163
    }
164
 
165
    /**
166
     * Escape token when it is "negated"
167
     */
168
    private function escape_token_string(&$text, $token) {
169
        $text = str_replace("~".$token, $this->protect($token), $text);
170
    }
171
 
172
    /**
173
     * Tag functions
174
     */
175
 
176
    protected function url_tag_rule($match) {
177
        if(strpos($match[0], "~") === 0) {
178
            return substr($match[0], 1);
179
        }
180
        else {
181
            $text = trim($match[0]);
182
            $options = array('href' => $text);
183
 
184
            return array($text, $options);
185
        }
186
    }
187
 
188
    protected function link_tag_rule($match) {
189
        $text = trim($match[1]);
190
 
191
        if(strpos($match[0], "~") === 0) {
192
            return substr($match[0], 1);
193
        }
194
        else {
195
            return $this->format_link($text);
196
        }
197
    }
198
 
199
    /**
200
     * Special treatment of // ** // ** //
201
     */
202
    protected function bold_tag_rule($match) {
203
        $text = $match[1];
204
        $this->rules($text, array('only' => array('italic')));
205
        if(strpos($text, "//") !== false) {
206
            $text = str_replace("//", $this->protect("//"), $text);
207
        }
208
        return array($text, array());
209
    }
210
 
211
    protected function image_tag_rule($match) {
212
        if(strpos($match[0], "~") === 0) {
213
            return substr($match[0], 1);
214
        }
215
 
216
        return $this->format_image($match[1], $match[2]);
217
    }
218
}