1<?php
2/**
3 * DokuWiki Plugin reproduce (Syntax Component)
4 *
5 * @description  :  This plugin allows to reproduce a code marked with a label
6 *                  located within the same source page, or in an other source
7 *                  page specified by its ID.
8 *
9 * @requires     :  "Plugin label", writen by Pascal Bihler <bihler@iai.uni-bonn.de>.
10 *
11 * @sytnax       :  <reproduce LABEL [PAGEID] />
12 *                      --> Where LABEL refers to a label name defined with <label NAME> ... </label>.
13 *                          --> Where NAME matches the regular expression [a-zA-Z0-9_]+
14 *                          --> Where ... refers to the code to reproduce.
15 *                      --> Where [PAGEID] (optional) refers to a source page ID
16 *                          that matches the regular expression [a-zA-Z0-9_:-]*.
17 *                          If PAGEID is omitted, the current page will be used.
18 *
19 * @license       :  GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
20 * @author        :  Patrice Bonneau <patrice.bonneau@live.ca>
21 * @lastupdate    :  2012-07-18
22 * @compatible    :  2012-01-25 "Angua"
23 */
24
25// must be run within Dokuwiki
26if (!defined('DOKU_INC'))     die();
27if (!defined('DOKU_LF'))      define('DOKU_LF', "\n");
28if (!defined('DOKU_TAB'))     define('DOKU_TAB', "\t");
29if (!defined('DOKU_PLUGIN'))  define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
30
31require_once DOKU_PLUGIN.'syntax.php';
32
33
34class syntax_plugin_reproduce extends DokuWiki_Syntax_Plugin {
35
36    var $LABEL_PATTERN = "[a-zA-Z0-9_]+";
37    var $PAGE_ID_PATTERN = "[a-zA-Z0-9_:-]*";
38
39
40    public function getType()    { return 'substition'; }
41    public function getPType()   { return 'normal'; }
42    public function getSort()    { return 100; }
43    public function getInfo()    {
44        return array(
45            'author' => 'Patrice Bonneau',
46            'email'  => 'patrice.bonneau@live.ca',
47            'date'   => '2012-05-18',
48            'name'   => 'Reproduce Plugin',
49            'desc'   => 'Allows to reproduce a code marked with a label located within the same source page, or in an other source page specified by its ID.',
50            'url'    => 'http://www.dokuwiki.org/plugin:reproduce',
51        );
52    }
53
54
55    public function connectTo($mode) {
56        $this->Lexer->addSpecialPattern('<reproduce\s+' . $this->LABEL_PATTERN . '\s*' . $this->PAGE_ID_PATTERN . '\s*/>', $mode, 'plugin_reproduce');
57    }
58
59
60    public function handle($match, $state, $pos, &$handler){
61        switch ($state) {
62            case DOKU_LEXER_SPECIAL :
63
64                // Find the label name and the optional source page ID in the <reproduce ... /> tag
65                if (preg_match('/<reproduce\s+(' . $this->LABEL_PATTERN . ')\s*(' . $this->PAGE_ID_PATTERN . ')\s*\/>/', $match, $matches)) {
66                    $labelName = $matches[1];
67                    $sourcePageID = $matches[2];
68
69                    if (!empty($sourcePageID)) {
70                        $sourcePageContent = io_readfile(wikiFN($sourcePageID));
71                    } else {
72                        // Load the source code of the current DokuWiki page
73                        global $ID;        // This is the current page ID
74                        $sourcePageContent = io_readfile(wikiFN($ID));
75                    }
76
77                    // To be compatible with the plugin � autonumbering �.
78                    // This will make sure to keep the original numbering and not restart
79                    // numbering at 1, by doing the numbering before to reproduce the code.
80                    $pluginList = plugin_list();
81                    if (in_array('autonumbering', $pluginList)) {
82                        $autonumbering = new syntax_plugin_autonumbering();
83                        $sourcePageContent = $autonumbering->doNumbering($sourcePageContent);
84                    }
85
86                    // Find the corresponding <label> and get its content
87                    if (preg_match('/<label\s+' . $labelName . '\s*>(.*?)<\/label>/ms', $sourcePageContent, $matches)) {
88                        $labelContent = $matches[1];
89                    } else {
90                        $labelContent = '\\\
91| @orange:**ERROR !**         | @orange:The source for **%%' . $match . '%%** can\'t be found. |
92| @yellow:\\\ **Syntax : **%%<reproduce LABEL [PAGEID] />%% \\\ \\\ --- Where LABEL refers to a label name defined with %%<label NAME> ... </label>%%. \\\ --------- Where NAME is an identifier consisting of letters (a-z, A-Z), number (0-9) and underscore (_). \\\ --------- Where **...** refers to the wikicode to reproduce. \\\ \\\ --- Where [PAGEID] (optional) refers to a source page ID, consisting of letters (a-z, A-Z), number (0-9), underscore (_) and a colon (:). \\\ --------- If PAGEID is omitted, the current page will be used. \\\\ \\\ ||
93|  @orange:**Contact your admin.**  ||
94\\\
95\\\
96';
97                    }
98                    return array($labelName, $labelContent);
99                }
100            break;
101        }
102        return array();
103    }
104
105
106    public function render($mode, &$renderer, $data) {
107        if(($mode == 'xhtml') && (!empty($data))) {
108            list($labelName, $labelContent) = $data;
109            $renderer->doc .= p_render('xhtml', p_get_instructions($labelContent), $info);
110            return true;
111        }
112        return false;
113    }
114}
115
116// vim:ts=4:sw=4:et:
117